diff --git a/.gitignore b/.gitignore index 4806959239..afa05ecbfd 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log + +# QUORUM +generated-release-notes.md \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d47b608849..2a20075f21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,20 +74,18 @@ matrix: os: linux dist: xenial script: - - sudo modprobe fuse - - sudo chmod 666 /dev/fuse - - sudo chown root:$USER /etc/fuse.conf - - go run build/ci.go install - - go run build/ci.go test -coverage $TEST_PACKAGES + - | + sudo modprobe fuse + sudo chmod 666 /dev/fuse + sudo chown root:$USER /etc/fuse.conf + go run build/ci.go install + QUORUM_IGNORE_TEST_PACKAGES=github.com/ethereum/go-ethereum/swarm,github.com/ethereum/go-ethereum/cmd/swarm go run build/ci.go test -coverage $TEST_PACKAGES - if: tag IS blank os: osx - osx_image: xcode9.2 # so we don't have to deal with Kernel Extension Consent UI which is never possible in CI script: - - brew update - - brew install caskroom/cask/brew-cask - - brew cask install osxfuse - - go run build/ci.go install - - go run build/ci.go test -coverage $TEST_PACKAGES + - | + go run build/ci.go install + QUORUM_IGNORE_TEST_PACKAGES=github.com/ethereum/go-ethereum/swarm,github.com/ethereum/go-ethereum/cmd/swarm go run build/ci.go test -coverage $TEST_PACKAGES - if: tag IS present os: linux @@ -101,7 +99,6 @@ matrix: - if: tag IS present os: osx - osx_image: xcode9.2 env: OUTPUT_FILE=geth_${TRAVIS_TAG}_darwin_amd64.tar.gz script: - build/env.sh go run build/ci.go install ./cmd/geth diff --git a/Makefile b/Makefile index f5376331b9..25668389fd 100644 --- a/Makefile +++ b/Makefile @@ -155,3 +155,44 @@ geth-windows-amd64: build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=windows/amd64 -v ./cmd/geth @echo "Windows amd64 cross compilation done:" @ls -ld $(GOBIN)/geth-windows-* | grep amd64 + +# QUORUM - BEGIN +RELEASE_NOTES_FILE := generated-release-notes.md +LAST_RELEASE_VERSION := $(shell git describe --tags --abbrev=0 @^) +REQUIRED_ENV_VARS := QUORUM_RELEASE BINTRAY_USER BINTRAY_API_KEY GITHUB_TOKEN +release-prepare: release-tools + @[ "${QUORUM_RELEASE}" ] || (echo "Please provide QUORUM_RELEASE env variable" ; exit 1) + @rm -f $(RELEASE_NOTES_FILE) + @echo "Last release: $(LAST_RELEASE_VERSION)" + @echo "This release: ${QUORUM_RELEASE}" + @echo "${QUORUM_RELEASE}\n\n" > $(RELEASE_NOTES_FILE) + @git log --pretty=format:%s $(LAST_RELEASE_VERSION)..@ >> $(RELEASE_NOTES_FILE) + @echo "$(RELEASE_NOTES_FILE) has been created" + +release: release-tools check-release-env + @jfrog bt version-show quorumengineering/quorum/geth/${QUORUM_RELEASE} --key ${BINTRAY_API_KEY} --user ${BINTRAY_USER} + @echo "\n\n| Filename | SHA256 Hash |" >> $(RELEASE_NOTES_FILE) + @echo "|:---------|:------------|" >> $(RELEASE_NOTES_FILE) + @curl -s -u ${BINTRAY_USER}:${BINTRAY_API_KEY} https://api.bintray.com/packages/quorumengineering/quorum/geth/versions/${QUORUM_RELEASE}/files \ + | jq '.[] | select(.name | endswith(".asc") | not) | "|[\(.name)](https://bintray.com/quorumengineering/quorum/download_file?file_path=\(.path))|`\(.sha256)`|"' -r \ + >> $(RELEASE_NOTES_FILE) + @hub release create -d -F $(RELEASE_NOTES_FILE) ${QUORUM_RELEASE} + +# make sure all API Keys are set +check-release-env: $(REQUIRED_ENV_VARS) + @[ -f "$(RELEASE_NOTES_FILE)" ] || (echo "Please run 'make release-prepare' and edit the release notes"; exit 1) + +$(REQUIRED_ENV_VARS): + @[ "${$@}" ] || (echo "Please provide $@ env variable" ; exit 1) + +release-tools: +ifeq (, $(shell which hub)) + @echo "Please install Github CLI from https://hub.github.com" +endif +ifeq (, $(shell which jfrog)) + @echo "Please install JFrog CLI from https://jfrog.com/getcli" +endif +ifeq (, $(shell which jq)) + @echo "Please install jq from https://stedolan.github.io/jq/download" +endif +# QUORUM - END \ No newline at end of file diff --git a/README.md b/README.md index 1d3742a8c3..c81f9306a6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ -# +# -Quorum Slack +Quorum Slack [![Build Status](https://travis-ci.org/jpmorganchase/quorum.svg?branch=master)](https://travis-ci.org/jpmorganchase/quorum) +[![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/quorumengineering/quorum)](https://hub.docker.com/r/quorumengineering/quorum/builds) +[![Documentation Status](https://readthedocs.org/projects/goquorum/badge/?version=latest)](http://docs.goquorum.com/en/latest/?badge=latest) [![Download](https://api.bintray.com/packages/quorumengineering/quorum/geth/images/download.svg)](https://bintray.com/quorumengineering/quorum/geth/_latestVersion) +[![Docker Pulls](https://img.shields.io/docker/pulls/quorumengineering/quorum)](https://hub.docker.com/r/quorumengineering/quorum) Quorum is an Ethereum-based distributed ledger protocol with transaction/contract privacy and new consensus mechanisms. @@ -21,13 +24,13 @@ Key enhancements over go-ethereum: ![Quorum Tessera Privacy Flow](https://raw.githubusercontent.com/jpmorganchase/quorum-docs/master/images/QuorumTransactionProcessing.JPG) -The above diagram is a high-level overview of the privacy architecture used by Quorum. For more in-depth discussion of the components, refer to the [wiki](https://github.com/jpmorganchase/quorum/wiki) pages. +The above diagram is a high-level overview of the privacy architecture used by Quorum. For more in-depth discussion of the components, refer to the [documentation site](https://docs.goquorum.com). ## Quickstart The quickest way to get started with Quorum is by following instructions in the [Quorum Examples](https://github.com/jpmorganchase/quorum-examples) repository. This allows you to quickly create a network of Quorum nodes, and includes a step-by-step demonstration of the privacy features of Quorum. ## Further Reading -Further documentation can be found in the [docs](docs/) folder and on the [wiki](https://github.com/jpmorganchase/quorum/wiki). +Further documentation can be found in the [docs](docs/) folder and on the [documentation site](https://docs.goquorum.com). ## Official Docker Containers The official docker containers can be found under https://hub.docker.com/u/quorumengineering/ @@ -36,38 +39,63 @@ The official docker containers can be found under https://hub.docker.com/u/quoru ## See also * [Quorum](https://github.com/jpmorganchase/quorum): this repository -* [Quorum Wiki](https://github.com/jpmorganchase/quorum/wiki) +* [Quorum Documentation](https://docs.goquorum.com) * [quorum-examples](https://github.com/jpmorganchase/quorum-examples): Quorum demonstration examples -* [Quorum Community Slack Inviter](https://clh7rniov2.execute-api.us-east-1.amazonaws.com/Express/): Quorum Slack community entry point +* [Quorum Community Slack Inviter](https://bit.ly/quorum-slack): Quorum Slack community entry point * Quorum Transaction Managers * [Constellation](https://github.com/jpmorganchase/constellation): Haskell implementation of peer-to-peer encrypted message exchange for transaction privacy * [Tessera](https://github.com/jpmorganchase/tessera): Java implementation of peer-to-peer encrypted message exchange for transaction privacy * Quorum supported consensuses - * [Raft Consensus Documentation](docs/raft.md) - * [Istanbul BFT Consensus Documentation](https://github.com/ethereum/EIPs/issues/650): [RPC API](https://github.com/jpmorganchase/quorum/blob/master/docs/istanbul-rpc-api.md) and [technical article](https://medium.com/getamis/istanbul-bft-ibft-c2758b7fe6ff). Please note that updated istanbul-tools is now hosted in [this](https://github.com/jpmorganchase/istanbul-tools/) repository + * [Raft Consensus Documentation](https://docs.goquorum.com/en/latest/Consensus/raft/) + * [Istanbul BFT Consensus Documentation](https://github.com/ethereum/EIPs/issues/650): [RPC API](https://docs.goquorum.com/en/latest/Consensus/ibft/istanbul-rpc-api.md) and [technical article](https://medium.com/getamis/istanbul-bft-ibft-c2758b7fe6ff). __Please note__ that updated istanbul-tools is now hosted in [this](https://github.com/jpmorganchase/istanbul-tools/) repository * [Clique POA Consensus Documentation](https://github.com/ethereum/EIPs/issues/225) and a [guide to setup clique json](https://modalduality.org/posts/puppeth/) with [puppeth](https://blog.ethereum.org/2017/04/14/geth-1-6-puppeth-master/) -* [ZSL](https://github.com/jpmorganchase/quorum/wiki/ZSL) wiki page and [documentation](https://github.com/jpmorganchase/zsl-q/blob/master/README.md) -* [quorum-tools](https://github.com/jpmorganchase/quorum-tools): local cluster orchestration, and integration testing tool +* Zero Knowledge on Quorum + * [ZSL](https://github.com/jpmorganchase/quorum/wiki/ZSL) wiki page and [documentation](https://github.com/jpmorganchase/zsl-q/blob/master/README.md) + * [Anonymous Zether](https://github.com/jpmorganchase/anonymous-zether) implementation +* [quorum-cloud](https://github.com/jpmorganchase/quorum-cloud): Tools to help deploy Quorum network in a cloud provider of choice +* [Cakeshop](https://github.com/jpmorganchase/cakeshop): An integrated development environment and SDK for Quorum ## Third Party Tools/Libraries The following Quorum-related libraries/applications have been created by Third Parties and as such are not specifically endorsed by J.P. Morgan. A big thanks to the developers for improving the tooling around Quorum! -* [Quorum Blockchain Explorer](https://github.com/blk-io/blk-explorer-free) - a Blockchain Explorer for Quorum which supports viewing private transactions +* [Quorum Blockchain Explorer](https://github.com/blk-io/epirus-free) - a Blockchain Explorer for Quorum which supports viewing private transactions * [Quorum-Genesis](https://github.com/davebryson/quorum-genesis) - A simple CL utility for Quorum to help populate the genesis file with voters and makers * [Quorum Maker](https://github.com/synechron-finlabs/quorum-maker/) - a utility to create Quorum nodes * [QuorumNetworkManager](https://github.com/ConsenSys/QuorumNetworkManager) - makes creating & managing Quorum networks easy * [ERC20 REST service](https://github.com/blk-io/erc20-rest-service) - a Quorum-supported RESTful service for creating and managing ERC-20 tokens * [Nethereum Quorum](https://github.com/Nethereum/Nethereum/tree/master/src/Nethereum.Quorum) - a .NET Quorum adapter -* [web3j-quorum](https://github.com/web3j/quorum) - an extension to the web3j Java library providing support for the Quorum API +* [web3j-quorum](https://github.com/web3j/web3j-quorum) - an extension to the web3j Java library providing support for the Quorum API * [Apache Camel](http://github.com/apache/camel) - an Apache Camel component providing support for the Quorum API using web3j library. Here is the artcile describing how to use Apache Camel with Ethereum and Quorum https://medium.com/@bibryam/enterprise-integration-for-ethereum-fa67a1577d43 - ## Contributing +Quorum is built on open source and we invite you to contribute enhancements. Upon review you will be required to complete a Contributor License Agreement (CLA) before we are able to merge. If you have any questions about the contribution process, please feel free to send an email to [info@goquorum.com](mailto:info@goquorum.com). + +## Reporting Security Bugs +Security is part of our commitment to our users. At Quorum we have a close relationship with the security community, we understand the realm, and encourage security researchers to become part of our mission of building secure reliable software. This section explains how to submit security bugs, and what to expect in return. + +All security bugs in [Quorum](https://github.com/jpmorganchase/quorum) and its ecosystem ([Tessera](https://github.com/jpmorganchase/tessera), [Constellation](https://github.com/jpmorganchase/constellation), [Cakeshop](https://github.com/jpmorganchase/cakeshop), ..etc) should be reported by email to [info@goquorum.com](mailto:info@goquorum.com). Please use the prefix **[security]** in your subject. This email is delivered to Quorum security team. Your email will be acknowledged, and you'll receive a more detailed response to your email as soon as possible indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement. + +If you have not received a reply to your email or you have not heard from the security team please contact any team member through quorum slack security channel. **Please note that Quorum slack channels are public discussion forum**. When escalating to this medium, please do not disclose the details of the issue. Simply state that you're trying to reach a member of the security team. + +#### Responsible Disclosure Process +Quorum project uses the following responsible disclosure process: + +- Once the security report is received it is assigned a primary handler. This person coordinates the fix and release process. +- The issue is confirmed and a list of affected software is determined. +- Code is audited to find any potential similar problems. +- If it is determined, in consultation with the submitter, that a CVE-ID is required, the primary handler will trigger the process. +- Fixes are applied to the public repository and a new release is issued. +- On the date that the fixes are applied, announcements are sent to Quorum-announce. +- At this point you would be able to disclose publicly your finding. + +**Note:** This process can take some time. Every effort will be made to handle the security bug in as timely a manner as possible, however it's important that we follow the process described above to ensure that disclosures are handled consistently. -Thank you for your interest in contributing to Quorum! +#### Receiving Security Updates +The best way to receive security announcements is to subscribe to the Quorum-announce mailing list/channel. Any messages pertaining to a security issue will be prefixed with **[security]**. -Quorum is built on open source and we invite you to contribute enhancements. Upon review you will be required to complete a Contributor License Agreement (CLA) before we are able to merge. If you have any questions about the contribution process, please feel free to send an email to [quorum_info@jpmorgan.com](mailto:quorum_info@jpmorgan.com). +Comments on This Policy +If you have any suggestions to improve this policy, please send an email to info@goquorum.com for discussion. ## License diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index e6bb0c3b52..304baffccb 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -22,6 +22,7 @@ import ( "io" "io/ioutil" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -60,3 +61,20 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { }, } } + +// Quorum +// +// NewWalletTransactor is a utility method to easily create a transaction signer +// from a wallet account +func NewWalletTransactor(w accounts.Wallet, from accounts.Account) *TransactOpts { + return &TransactOpts{ + From: from.Address, + Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + signature, err := w.SignHash(from, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + } +} diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index ca60cc1b43..e8f5b1faf7 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -81,7 +81,9 @@ type ContractTransactor interface { // for setting a reasonable default. EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) // SendTransaction injects the transaction into the pending pool for execution. - SendTransaction(ctx context.Context, tx *types.Transaction) error + SendTransaction(ctx context.Context, tx *types.Transaction, args PrivateTxArgs) error + // PreparePrivateTransaction send the private transaction to Tessera/Constellation's /storeraw API using HTTP + PreparePrivateTransaction(data []byte, privateFrom string) ([]byte, error) } // ContractFilterer defines the methods needed to access log events using one-off diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fe06cb70af..75407f585f 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -24,6 +24,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -81,6 +83,20 @@ func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBac return backend } +// Quorum +// +// Create a simulated backend based on existing Ethereum service +func NewSimulatedBackendFrom(ethereum *eth.Ethereum) *SimulatedBackend { + backend := &SimulatedBackend{ + database: ethereum.ChainDb(), + blockchain: ethereum.BlockChain(), + config: ethereum.ChainConfig(), + events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{ethereum.ChainDb(), ethereum.BlockChain()}, false), + } + backend.rollback() + return backend +} + // Commit imports all the pending transactions as a single block and starts a // fresh new state. func (b *SimulatedBackend) Commit() { @@ -293,7 +309,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // SendTransaction updates the pending block to include the given transaction. // It panics if the transaction is invalid. -func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { +func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction, args bind.PrivateTxArgs) error { b.mu.Lock() defer b.mu.Unlock() @@ -319,6 +335,11 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa return nil } +// PreparePrivateTransaction dummy implementation +func (b *SimulatedBackend) PreparePrivateTransaction(data []byte, privateFrom string) ([]byte, error) { + return data, nil +} + // FilterLogs executes a log filter operation, blocking during execution and // returning all the results in one batch. // diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 83ad1c8ae7..c53a77a2f1 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -34,6 +34,13 @@ import ( // sign the transaction before submission. type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error) +// Quorum +// +// Additional arguments in order to support transaction privacy +type PrivateTxArgs struct { + PrivateFor []string `json:"privateFor"` +} + // CallOpts is the collection of options to fine tune a contract call request. type CallOpts struct { Pending bool // Whether to operate on the pending state or the last known one @@ -54,6 +61,10 @@ type TransactOpts struct { GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) + + // Quorum + PrivateFrom string // The public key of the Tessera/Constellation identity to send this tx from. + PrivateFor []string // The public keys of the Tessera/Constellation identities this tx is intended for. } // FilterOpts is the collection of options to fine tune filtering for events @@ -231,16 +242,36 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i } else { rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input) } + + // If this transaction is private, we need to substitute the data payload + // with the hash of the transaction from tessera/constellation. + if opts.PrivateFor != nil { + var payload []byte + payload, err = c.transactor.PreparePrivateTransaction(rawTx.Data(), opts.PrivateFrom) + if err != nil { + return nil, err + } + rawTx = c.createPrivateTransaction(rawTx, payload) + } + + // Choose signer to sign transaction if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") } - signedTx, err := opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) + var signedTx *types.Transaction + if rawTx.IsPrivate() { + signedTx, err = opts.Signer(types.QuorumPrivateTxSigner{}, opts.From, rawTx) + } else { + signedTx, err = opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) + } if err != nil { return nil, err } - if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx); err != nil { + + if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx, PrivateTxArgs{PrivateFor: opts.PrivateFor}); err != nil { return nil, err } + return signedTx, nil } @@ -340,6 +371,18 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) return parseTopics(out, indexed, log.Topics[1:]) } +// createPrivateTransaction replaces the payload of private transaction to the hash from Tessera/Constellation +func (c *BoundContract) createPrivateTransaction(tx *types.Transaction, payload []byte) *types.Transaction { + var privateTx *types.Transaction + if tx.To() == nil { + privateTx = types.NewContractCreation(tx.Nonce(), tx.Value(), tx.Gas(), tx.GasPrice(), payload) + } else { + privateTx = types.NewTransaction(tx.Nonce(), c.address, tx.Value(), tx.Gas(), tx.GasPrice(), payload) + } + privateTx.SetPrivate() + return privateTx +} + // ensureContext is a helper method to ensure a context is not nil, even if the // user specified it as such. func ensureContext(ctx context.Context) context.Context { diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 8f4092971f..d9ec08d587 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -76,7 +76,7 @@ func TestWaitDeployed(t *testing.T) { }() // Send and mine the transaction. - backend.SendTransaction(ctx, tx) + backend.SendTransaction(ctx, tx, bind.PrivateTxArgs{}) backend.Commit() select { diff --git a/accounts/accounts.go b/accounts/accounts.go index 79f8632e24..cb1eae2815 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -111,7 +111,7 @@ type Wallet interface { // about which fields or actions are needed. The user may retry by providing // the needed details via SignTxWithPassphrase, or by other means (e.g. unlock // the account in a keystore). - SignTx(account Account, tx *types.Transaction, chainID *big.Int, isQuorum bool) (*types.Transaction, error) + SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) // SignHashWithPassphrase requests the wallet to sign the given hash with the // given passphrase as extra authentication information. diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index cd5e61be1a..d000c70c2e 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -25,6 +25,7 @@ import ( crand "crypto/rand" "errors" "fmt" + "github.com/ethereum/go-ethereum/log" "math/big" "os" "path/filepath" @@ -268,7 +269,7 @@ func (ks *KeyStore) SignHash(a accounts.Account, hash []byte) ([]byte, error) { } // SignTx signs the given transaction with the requested account. -func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *big.Int, isQuorum bool) (*types.Transaction, error) { +func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { // Look up the key to sign with and abort if it cannot be found ks.mu.RLock() defer ks.mu.RUnlock() @@ -277,8 +278,15 @@ func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *b if !found { return nil, ErrLocked } + + // start quorum specific + if tx.IsPrivate() { + log.Info("Private transaction signing with QuorumPrivateTxSigner") + return types.SignTx(tx, types.QuorumPrivateTxSigner{}, unlockedKey.PrivateKey) + } // End quorum specific + // Depending on the presence of the chain ID, sign with EIP155 or homestead - if chainID != nil && !tx.IsPrivate() { + if chainID != nil { return types.SignTx(tx, types.NewEIP155Signer(chainID), unlockedKey.PrivateKey) } return types.SignTx(tx, types.HomesteadSigner{}, unlockedKey.PrivateKey) @@ -305,6 +313,9 @@ func (ks *KeyStore) SignTxWithPassphrase(a accounts.Account, passphrase string, } defer zeroKey(key.PrivateKey) + if tx.IsPrivate() { + return types.SignTx(tx, types.QuorumPrivateTxSigner{}, key.PrivateKey) + } // Depending on the presence of the chain ID, sign with EIP155 or homestead if chainID != nil { return types.SignTx(tx, types.NewEIP155Signer(chainID), key.PrivateKey) diff --git a/accounts/keystore/keystore_wallet.go b/accounts/keystore/keystore_wallet.go index 6f809a9bfb..758fdfe364 100644 --- a/accounts/keystore/keystore_wallet.go +++ b/accounts/keystore/keystore_wallet.go @@ -98,7 +98,7 @@ func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte // with the given account. If the wallet does not wrap this particular account, // an error is returned to avoid account leakage (even though in theory we may // be able to sign via our shared keystore backend). -func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int, isQuorum bool) (*types.Transaction, error) { +func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { // Make sure the requested account is contained within if account.Address != w.account.Address { return nil, accounts.ErrUnknownAccount @@ -107,7 +107,7 @@ func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign - return w.keystore.SignTx(account, tx, chainID, isQuorum) + return w.keystore.SignTx(account, tx, chainID) } // SignHashWithPassphrase implements accounts.Wallet, attempting to sign the diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index fdaf7a946a..f8207147ba 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -509,12 +509,12 @@ func (w *wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) // Note, if the version of the Ethereum application running on the Ledger wallet is // too old to sign EIP-155 transactions, but such is requested nonetheless, an error // will be returned opposed to silently signing in Homestead mode. -func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int, isQuorum bool) (*types.Transaction, error) { +func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { w.stateLock.RLock() // Comms have own mutex, this is for the state fields defer w.stateLock.RUnlock() - if isQuorum { - return nil, errors.New("Signing Quorum transactions with a USB wallet not yet supported") + if tx.IsPrivate() { + return nil, errors.New("Signing Quorum Private transactions with a USB wallet not yet supported") } // If the wallet is closed, abort @@ -563,5 +563,5 @@ func (w *wallet) SignHashWithPassphrase(account accounts.Account, passphrase str // transaction with the given account using passphrase as extra authentication. // Since USB wallets don't rely on passphrases, these are silently ignored. func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - return w.SignTx(account, tx, chainID, false) + return w.SignTx(account, tx, chainID) } diff --git a/build/ci.go b/build/ci.go index 1bbc944714..99550926fc 100644 --- a/build/ci.go +++ b/build/ci.go @@ -329,6 +329,7 @@ func doTest(cmdline []string) { packages = flag.CommandLine.Args() } packages = build.ExpandPackagesNoVendor(packages) + packages = build.IgnorePackages(packages) // Run the actual tests. // Test a single package at a time. CI builders are slow diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index c4aadfbf43..18503b7ed3 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -41,6 +41,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" @@ -473,7 +475,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil)) tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil) - signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID, false) + signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID) if err != nil { f.lock.Unlock() if err = sendError(conn, err); err != nil { @@ -483,7 +485,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { continue } // Submit the transaction and mark as funded if successful - if err := f.client.SendTransaction(context.Background(), signed); err != nil { + if err := f.client.SendTransaction(context.Background(), signed, bind.PrivateTxArgs{}); err != nil { f.lock.Unlock() if err = sendError(conn, err); err != nil { log.Warn("Failed to send transaction transmission error to client", "err", err) diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 3ea22ccfab..ac988cb010 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -155,7 +155,24 @@ Passphrase: {{.InputLine "foobar"}} } } +func TestGethDoesntStartWithoutPrivateTransactionManagerVariableSet(t *testing.T) { + defer SetResetPrivateConfig("")() + + datadir := tmpDatadirWithKeystore(t) + geth := runGeth(t, + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", + "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") + geth.ExpectExit() + + expectedText := "the PRIVATE_CONFIG environment variable must be specified for Quorum" + result := strings.TrimSpace(geth.StderrText()) + if result != expectedText { + geth.Fatalf("bad stderr text. want '%s', got '%s'", expectedText, result) + } +} + func TestUnlockFlagWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", @@ -222,6 +239,7 @@ func TestUnlockFlagPasswordFile(t *testing.T) { } func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", @@ -271,6 +289,7 @@ In order to avoid this warning, you need to remove the following duplicate key f } func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 8c2b26feb3..f3555b8907 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -159,6 +159,10 @@ func makeFullNode(ctx *cli.Context) *node.Node { ethChan := utils.RegisterEthService(stack, &cfg.Eth) + if cfg.Node.IsPermissionEnabled() { + utils.RegisterPermissionService(ctx, stack) + } + if ctx.GlobalBool(utils.RaftModeFlag.Name) { RegisterRaftService(stack, ctx, cfg, ethChan) } @@ -213,7 +217,7 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth blockTimeMillis := ctx.GlobalInt(utils.RaftBlockTimeFlag.Name) datadir := ctx.GlobalString(utils.DataDirFlag.Name) joinExistingId := ctx.GlobalInt(utils.RaftJoinExistingFlag.Name) - + useDns := ctx.GlobalBool(utils.RaftDNSEnabledFlag.Name) raftPort := uint16(ctx.GlobalInt(utils.RaftPortFlag.Name)) if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { @@ -251,8 +255,7 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth } ethereum := <-ethChan - - return raft.New(ctx, ethereum.ChainConfig(), myId, raftPort, joinExisting, blockTimeNanos, ethereum, peers, datadir) + return raft.New(ctx, ethereum.ChainConfig(), myId, raftPort, joinExisting, blockTimeNanos, ethereum, peers, datadir, useDns) }); err != nil { utils.Fatalf("Failed to register the Raft service: %v", err) } @@ -272,3 +275,9 @@ func quorumValidateConsensus(stack *node.Node, isRaft bool) { utils.Fatalf("Consensus not specified. Exiting!!") } } + +// quorumValidatePrivateTransactionManager returns whether the "PRIVATE_CONFIG" +// environment variable is set +func quorumValidatePrivateTransactionManager() bool { + return os.Getenv("PRIVATE_CONFIG") != "" +} diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 849f3a3560..1d3f986460 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -33,7 +33,7 @@ import ( const ( ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0" - httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" + httpAPIs = "admin:1.0 eth:1.0 net:1.0 rpc:1.0 web3:1.0" nodeKey = "b68c0338aa4b266bf38ebe84c6199ae9fac8b29f32998b3ed2fbeafebe8d65c9" ) @@ -70,6 +70,7 @@ var genesis = `{ // Tests that a node embedded within a console can be started up properly and // then terminated by closing the input stream. func TestConsoleWelcome(t *testing.T) { + defer SetResetPrivateConfig("ignore")() coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" datadir := setupIstanbul(t) @@ -107,6 +108,7 @@ at block: 0 ({{niltime}}) // Tests that a console can be attached to a running node via various means. func TestIPCAttachWelcome(t *testing.T) { + defer SetResetPrivateConfig("ignore")() // Configure the instance for IPC attachement coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" var ipc string @@ -134,6 +136,7 @@ func TestIPCAttachWelcome(t *testing.T) { } func TestHTTPAttachWelcome(t *testing.T) { + defer SetResetPrivateConfig("ignore")() coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P @@ -142,7 +145,7 @@ func TestHTTPAttachWelcome(t *testing.T) { geth := runGeth(t, "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--rpc", "--rpcport", port) + "--etherbase", coinbase, "--rpc", "--rpcport", port, "--rpcapi", "admin,eth,net,web3") time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open testAttachWelcome(t, geth, "http://localhost:"+port, httpAPIs) @@ -152,6 +155,7 @@ func TestHTTPAttachWelcome(t *testing.T) { } func TestWSAttachWelcome(t *testing.T) { + defer SetResetPrivateConfig("ignore")() coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P @@ -160,7 +164,7 @@ func TestWSAttachWelcome(t *testing.T) { geth := runGeth(t, "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--ws", "--wsport", port) + "--etherbase", coinbase, "--ws", "--wsport", port, "--wsapi", "admin,eth,net,web3") time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open testAttachWelcome(t, geth, "ws://localhost:"+port, httpAPIs) @@ -183,7 +187,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { attach.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase }) attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) - attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) + attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") || strings.Contains(apis, "admin") }) attach.SetTemplateFunc("datadir", func() string { return geth.Datadir }) attach.SetTemplateFunc("apis", func() string { return apis }) @@ -231,3 +235,11 @@ func setupIstanbul(t *testing.T) string { return datadir } + +func SetResetPrivateConfig(value string) func() { + existingValue := os.Getenv("PRIVATE_CONFIG") + os.Setenv("PRIVATE_CONFIG", value) + return func() { + os.Setenv("PRIVATE_CONFIG", existingValue) + } +} \ No newline at end of file diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 701d608bba..1b4e59f1be 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -18,6 +18,7 @@ package main import ( + "errors" "fmt" "math" "os" @@ -38,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/permission" "gopkg.in/urfave/cli.v1" ) @@ -133,14 +135,17 @@ var ( utils.EWASMInterpreterFlag, utils.EVMInterpreterFlag, configFileFlag, + // Quorum utils.EnableNodePermissionFlag, utils.RaftModeFlag, utils.RaftBlockTimeFlag, utils.RaftJoinExistingFlag, utils.RaftPortFlag, + utils.RaftDNSEnabledFlag, utils.EmitCheckpointsFlag, utils.IstanbulRequestTimeoutFlag, utils.IstanbulBlockPeriodFlag, + // End-Quorum } rpcFlags = []cli.Flag{ @@ -270,6 +275,11 @@ func geth(ctx *cli.Context) error { if args := ctx.Args(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } + + if !quorumValidatePrivateTransactionManager() { + return errors.New("the PRIVATE_CONFIG environment variable must be specified for Quorum") + } + node := makeFullNode(ctx) startNode(ctx, node) @@ -341,6 +351,20 @@ func startNode(ctx *cli.Context, stack *node.Node) { } } }() + + // Quorum + // + // checking if permissions is enabled and staring the permissions service + if stack.IsPermissionEnabled() { + var permissionService *permission.PermissionCtrl + if err := stack.Service(&permissionService); err != nil { + utils.Fatalf("Permission service not runnning: %v", err) + } + if err := permissionService.AfterStart(); err != nil { + utils.Fatalf("Permission service post construct failure: %v", err) + } + } + // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { // Mining only makes sense if a full Ethereum node is running @@ -366,4 +390,5 @@ func startNode(ctx *cli.Context, stack *node.Node) { utils.Fatalf("Failed to start mining: %v", err) } } + } diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 40fe83acb2..b7d974af10 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -128,17 +128,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.TxPoolLifetimeFlag, }, }, - { - Name: "ETHASH", - Flags: []cli.Flag{ - utils.EthashCacheDirFlag, - utils.EthashCachesInMemoryFlag, - utils.EthashCachesOnDiskFlag, - utils.EthashDatasetDirFlag, - utils.EthashDatasetsInMemoryFlag, - utils.EthashDatasetsOnDiskFlag, - }, - }, { Name: "PERFORMANCE TUNING", Flags: []cli.Flag{ @@ -161,6 +150,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.RaftBlockTimeFlag, utils.RaftJoinExistingFlag, utils.RaftPortFlag, + utils.RaftDNSEnabledFlag, }, }, { @@ -270,16 +260,16 @@ var AppHelpFlagGroups = []flagGroup{ utils.MinerLegacyEtherbaseFlag, utils.MinerLegacyExtraDataFlag, }, - }, - { - Name: "MISC", - },{ + }, { Name: "ISTANBUL", Flags: []cli.Flag{ utils.IstanbulRequestTimeoutFlag, utils.IstanbulBlockPeriodFlag, }, }, + { + Name: "MISC", + }, } // byCategory sorts an array of flagGroup by Name in the order diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e9a1ed99bd..59fd652c22 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -27,6 +27,10 @@ import ( "strconv" "strings" + "github.com/ethereum/go-ethereum/permission" + + "time" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" @@ -57,7 +61,6 @@ import ( "github.com/ethereum/go-ethereum/params" whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" "gopkg.in/urfave/cli.v1" - "time" ) var ( @@ -591,6 +594,7 @@ var ( Usage: "The raft ID to assume when joining an pre-existing cluster", Value: 0, } + EmitCheckpointsFlag = cli.BoolFlag{ Name: "emitcheckpoints", Usage: "If enabled, emit specially formatted logging checkpoints", @@ -600,6 +604,10 @@ var ( Usage: "The port to bind for the raft transport", Value: 50400, } + RaftDNSEnabledFlag = cli.BoolFlag{ + Name: "raftdnsenable", + Usage: "Enable DNS resolution of peers", + } // Quorum EnableNodePermissionFlag = cli.BoolFlag{ @@ -875,10 +883,11 @@ func makeDatabaseHandles() int { if err != nil { Fatalf("Failed to retrieve file descriptor allowance: %v", err) } - if err := fdlimit.Raise(uint64(limit)); err != nil { + raised, err := fdlimit.Raise(uint64(limit)) + if err != nil { Fatalf("Failed to raise file descriptor allowance: %v", err) } - return limit / 2 // Leave half for networking and other stuff + return int(raised / 2) // Leave half for networking and other stuff } // MakeAddress converts an account specified directly as a hex encoded string or @@ -1218,6 +1227,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { } cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive" + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { cfg.TrieCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 } @@ -1383,6 +1393,27 @@ func RegisterEthStatsService(stack *node.Node, url string) { } } +// Quorum +// +// Configure smart-contract-based permissioning service +func RegisterPermissionService(ctx *cli.Context, stack *node.Node) { + if err := stack.Register(func(sctx *node.ServiceContext) (node.Service, error) { + permissionConfig, err := permission.ParsePermissionConfig(stack.DataDir()) + if err != nil { + return nil, fmt.Errorf("loading of %s failed due to %v", params.PERMISSION_MODEL_CONFIG, err) + } + // start the permissions management service + pc, err := permission.NewQuorumPermissionCtrl(stack, &permissionConfig) + if err != nil { + return nil, fmt.Errorf("failed to load the permission contracts as given in %s due to %v", params.PERMISSION_MODEL_CONFIG, err) + } + return pc, nil + }); err != nil { + Fatalf("Failed to register the permission service: %v", err) + } + log.Info("permission service registered") +} + func SetupMetrics(ctx *cli.Context) { if metrics.Enabled { log.Info("Enabling metrics collection") @@ -1464,6 +1495,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) } + cache := &core.CacheConfig{ Disabled: ctx.GlobalString(GCModeFlag.Name) == "archive", TrieNodeLimit: eth.DefaultConfig.TrieCache, diff --git a/common/fdlimit/fdlimit_darwin.go b/common/fdlimit/fdlimit_darwin.go new file mode 100644 index 0000000000..88dd0f56cb --- /dev/null +++ b/common/fdlimit/fdlimit_darwin.go @@ -0,0 +1,71 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package fdlimit + +import "syscall" + +// hardlimit is the number of file descriptors allowed at max by the kernel. +const hardlimit = 10240 + +// Raise tries to maximize the file descriptor allowance of this process +// to the maximum hard-limit allowed by the OS. +// Returns the size it was set to (may differ from the desired 'max') +func Raise(max uint64) (uint64, error) { + // Get the current limit + var limit syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + // Try to update the limit to the max allowance + limit.Cur = limit.Max + if limit.Cur > max { + limit.Cur = max + } + if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + // MacOS can silently apply further caps, so retrieve the actually set limit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + return limit.Cur, nil +} + +// Current retrieves the number of file descriptors allowed to be opened by this +// process. +func Current() (int, error) { + var limit syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + return int(limit.Cur), nil +} + +// Maximum retrieves the maximum number of file descriptors this process is +// allowed to request for itself. +func Maximum() (int, error) { + // Retrieve the maximum allowed by dynamic OS limits + var limit syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err + } + // Cap it to OPEN_MAX (10240) because macos is a special snowflake + if limit.Max > hardlimit { + limit.Max = hardlimit + } + return int(limit.Max), nil +} diff --git a/common/fdlimit/fdlimit_freebsd.go b/common/fdlimit/fdlimit_freebsd.go index c126b0c265..0d8727138e 100644 --- a/common/fdlimit/fdlimit_freebsd.go +++ b/common/fdlimit/fdlimit_freebsd.go @@ -26,11 +26,11 @@ import "syscall" // Raise tries to maximize the file descriptor allowance of this process // to the maximum hard-limit allowed by the OS. -func Raise(max uint64) error { +func Raise(max uint64) (uint64, error) { // Get the current limit var limit syscall.Rlimit if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { - return err + return 0, err } // Try to update the limit to the max allowance limit.Cur = limit.Max @@ -38,9 +38,12 @@ func Raise(max uint64) error { limit.Cur = int64(max) } if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { - return err + return 0, err + } + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err } - return nil + return uint64(limit.Cur), nil } // Current retrieves the number of file descriptors allowed to be opened by this diff --git a/common/fdlimit/fdlimit_test.go b/common/fdlimit/fdlimit_test.go index a9ee9ab36a..21362b8463 100644 --- a/common/fdlimit/fdlimit_test.go +++ b/common/fdlimit/fdlimit_test.go @@ -36,7 +36,7 @@ func TestFileDescriptorLimits(t *testing.T) { if limit, err := Current(); err != nil || limit <= 0 { t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err) } - if err := Raise(uint64(target)); err != nil { + if _, err := Raise(uint64(target)); err != nil { t.Fatalf("failed to raise file allowance") } if limit, err := Current(); err != nil || limit < target { diff --git a/common/fdlimit/fdlimit_unix.go b/common/fdlimit/fdlimit_unix.go index a258132353..e5a575f7a7 100644 --- a/common/fdlimit/fdlimit_unix.go +++ b/common/fdlimit/fdlimit_unix.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// +build linux darwin netbsd openbsd solaris +// +build linux netbsd openbsd solaris package fdlimit @@ -22,11 +22,12 @@ import "syscall" // Raise tries to maximize the file descriptor allowance of this process // to the maximum hard-limit allowed by the OS. -func Raise(max uint64) error { +// Returns the size it was set to (may differ from the desired 'max') +func Raise(max uint64) (uint64, error) { // Get the current limit var limit syscall.Rlimit if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { - return err + return 0, err } // Try to update the limit to the max allowance limit.Cur = limit.Max @@ -34,9 +35,13 @@ func Raise(max uint64) error { limit.Cur = max } if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { - return err + return 0, err + } + // MacOS can silently apply further caps, so retrieve the actually set limit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil { + return 0, err } - return nil + return limit.Cur, nil } // Current retrieves the number of file descriptors allowed to be opened by this diff --git a/common/fdlimit/fdlimit_windows.go b/common/fdlimit/fdlimit_windows.go index 863c58bedf..f472153662 100644 --- a/common/fdlimit/fdlimit_windows.go +++ b/common/fdlimit/fdlimit_windows.go @@ -16,28 +16,31 @@ package fdlimit -import "errors" +import "fmt" + +// hardlimit is the number of file descriptors allowed at max by the kernel. +const hardlimit = 16384 // Raise tries to maximize the file descriptor allowance of this process // to the maximum hard-limit allowed by the OS. -func Raise(max uint64) error { +func Raise(max uint64) (uint64, error) { // This method is NOP by design: // * Linux/Darwin counterparts need to manually increase per process limits // * On Windows Go uses the CreateFile API, which is limited to 16K files, non // changeable from within a running process // This way we can always "request" raising the limits, which will either have // or not have effect based on the platform we're running on. - if max > 16384 { - return errors.New("file descriptor limit (16384) reached") + if max > hardlimit { + return hardlimit, fmt.Errorf("file descriptor limit (%d) reached", hardlimit) } - return nil + return max, nil } // Current retrieves the number of file descriptors allowed to be opened by this // process. func Current() (int, error) { // Please see Raise for the reason why we use hard coded 16K as the limit - return 16384, nil + return hardlimit, nil } // Maximum retrieves the maximum number of file descriptors this process is diff --git a/common/types.go b/common/types.go index 8efddb532f..9c366ec889 100644 --- a/common/types.go +++ b/common/types.go @@ -175,7 +175,6 @@ func BytesToAddress(b []byte) Address { func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } // dep: Istanbul - // BigToAddress returns Address with byte values of b. // If b is larger than len(h), b will be cropped from the left. func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 8d90f45de8..8b4d4466ba 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -302,7 +302,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent * } limit := parent.GasLimit / params.OriginalGasLimitBoundDivisor - if uint64(diff) >= limit || header.GasLimit < params.OriginnalMinGasLimit { + if uint64(diff) >= limit || header.GasLimit < params.OriginalMinGasLimit { return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) } // Verify that the block number is parent's +1 diff --git a/consensus/istanbul/backend/api.go b/consensus/istanbul/backend/api.go index ee2a3e9d94..bfbf6c9b10 100644 --- a/consensus/istanbul/backend/api.go +++ b/consensus/istanbul/backend/api.go @@ -29,6 +29,66 @@ type API struct { istanbul *backend } +// BlockSigners is contains who created and who signed a particular block, denoted by its number and hash +type BlockSigners struct { + Number uint64 + Hash common.Hash + Author common.Address + Committers []common.Address +} + +// NodeAddress returns the public address that is used to sign block headers in IBFT +func (api *API) NodeAddress() common.Address { + return api.istanbul.Address() +} + +// GetSignersFromBlock returns the signers and minter for a given block number, or the +// latest block available if none is specified +func (api *API) GetSignersFromBlock(number *rpc.BlockNumber) (*BlockSigners, error) { + // Retrieve the requested block number (or current if none requested) + var header *types.Header + if number == nil || *number == rpc.LatestBlockNumber { + header = api.chain.CurrentHeader() + } else { + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) + } + + if header == nil { + return nil, errUnknownBlock + } + + return api.signers(header) +} + +// GetSignersFromBlockByHash returns the signers and minter for a given block hash +func (api *API) GetSignersFromBlockByHash(hash common.Hash) (*BlockSigners, error) { + header := api.chain.GetHeaderByHash(hash) + if header == nil { + return nil, errUnknownBlock + } + + return api.signers(header) +} + +func (api *API) signers(header *types.Header) (*BlockSigners, error) { + author, err := api.istanbul.Author(header) + if err != nil { + return nil, err + } + + committers, err := api.istanbul.Signers(header) + if err != nil { + return nil, err + } + + return &BlockSigners{ + Number: header.Number.Uint64(), + Hash: header.Hash(), + Author: author, + Committers: committers, + }, nil +} + // GetSnapshot retrieves the state snapshot at a given block. func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { // Retrieve the requested block number (or current if none requested) diff --git a/consensus/istanbul/backend/backend.go b/consensus/istanbul/backend/backend.go index bf9fb00a6b..0676b8ef90 100644 --- a/consensus/istanbul/backend/backend.go +++ b/consensus/istanbul/backend/backend.go @@ -316,8 +316,6 @@ func (sb *backend) HasBadProposal(hash common.Hash) bool { return sb.hasBadBlock(hash) } - - func (sb *backend) Close() error { return nil -} \ No newline at end of file +} diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go index 3fd681bd2c..0c24f91cd9 100644 --- a/consensus/istanbul/backend/engine.go +++ b/consensus/istanbul/backend/engine.go @@ -27,8 +27,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/istanbul" - istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core" "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto/sha3" @@ -103,6 +103,31 @@ func (sb *backend) Author(header *types.Header) (common.Address, error) { return ecrecover(header) } +// Signers extracts all the addresses who have signed the given header +// It will extract for each seal who signed it, regardless of if the seal is +// repeated +func (sb *backend) Signers(header *types.Header) ([]common.Address, error) { + extra, err := types.ExtractIstanbulExtra(header) + if err != nil { + return []common.Address{}, err + } + + var addrs []common.Address + proposalSeal := istanbulCore.PrepareCommittedSeal(header.Hash()) + + // 1. Get committed seals from current header + for _, seal := range extra.CommittedSeal { + // 2. Get the original address by seal and parent block hash + addr, err := istanbul.GetSignatureAddress(proposalSeal, seal) + if err != nil { + sb.logger.Error("not a valid address", "err", err) + return nil, errInvalidSignature + } + addrs = append(addrs, addr) + } + return addrs, nil +} + // VerifyHeader checks whether a header conforms to the consensus rules of a // given engine. Verifying the seal may be done optionally here, or explicitly // via the VerifySeal method. @@ -271,26 +296,20 @@ func (sb *backend) verifyCommittedSeals(chain consensus.ChainReader, header *typ validators := snap.ValSet.Copy() // Check whether the committed seals are generated by parent's validators validSeal := 0 - proposalSeal := istanbulCore.PrepareCommittedSeal(header.Hash()) - // 1. Get committed seals from current header - for _, seal := range extra.CommittedSeal { - // 2. Get the original address by seal and parent block hash - addr, err := istanbul.GetSignatureAddress(proposalSeal, seal) - if err != nil { - sb.logger.Error("not a valid address", "err", err) - return errInvalidSignature - } - // Every validator can have only one seal. If more than one seals are signed by a - // validator, the validator cannot be found and errInvalidCommittedSeals is returned. + committers, err := sb.Signers(header) + if err != nil { + return err + } + for _, addr := range committers { if validators.RemoveValidator(addr) { - validSeal += 1 - } else { - return errInvalidCommittedSeals + validSeal++ + continue } + return errInvalidCommittedSeals } - // The length of validSeal should be larger than number of faulty node + 1 - if validSeal <= 2*snap.ValSet.F() { + // The length of validSeal should be larger than number of faulty node + 1 + if validSeal <= snap.ValSet.F() { return errInvalidCommittedSeals } @@ -416,42 +435,45 @@ func (sb *backend) Seal(chain consensus.ChainReader, block *types.Block, results return err } - // wait for the timestamp of header, use this to adjust the block period - delay := time.Unix(block.Header().Time.Int64(), 0).Sub(now()) - select { - case <-time.After(delay): - case <-stop: - results <- nil - return nil - } - - // get the proposed block hash and clear it if the seal() is completed. - sb.sealMu.Lock() - sb.proposedBlockHash = block.Hash() - clear := func() { - sb.proposedBlockHash = common.Hash{} - sb.sealMu.Unlock() - } - defer clear() + delay := time.Unix(header.Time.Int64(), 0).Sub(now()) - // post block into Istanbul engine - go sb.EventMux().Post(istanbul.RequestEvent{ - Proposal: block, - }) - for { + go func() { + // wait for the timestamp of header, use this to adjust the block period select { - case result := <-sb.commitCh: - // if the block hash and the hash from channel are the same, - // return the result. Otherwise, keep waiting the next hash. - if result != nil && block.Hash() == result.Hash() { - results <- result - return nil - } + case <-time.After(delay): case <-stop: results <- nil - return nil + return } - } + + // get the proposed block hash and clear it if the seal() is completed. + sb.sealMu.Lock() + sb.proposedBlockHash = block.Hash() + + defer func() { + sb.proposedBlockHash = common.Hash{} + sb.sealMu.Unlock() + }() + // post block into Istanbul engine + go sb.EventMux().Post(istanbul.RequestEvent{ + Proposal: block, + }) + for { + select { + case result := <-sb.commitCh: + // if the block hash and the hash from channel are the same, + // return the result. Otherwise, keep waiting the next hash. + if result != nil && block.Hash() == result.Hash() { + results <- result + return + } + case <-stop: + results <- nil + return + } + } + }() + return nil } // update timestamp and signature of the block based on its number of transactions @@ -616,7 +638,6 @@ func sigHash(header *types.Header) (hash common.Hash) { return hash } - // SealHash returns the hash of a block prior to it being sealed. func (sb *backend) SealHash(header *types.Header) common.Hash { return sigHash(header) diff --git a/consensus/istanbul/backend/engine_test.go b/consensus/istanbul/backend/engine_test.go index d14032afca..fa5c4a4fde 100644 --- a/consensus/istanbul/backend/engine_test.go +++ b/consensus/istanbul/backend/engine_test.go @@ -195,30 +195,44 @@ func TestSealCommittedOtherHash(t *testing.T) { chain, engine := newBlockChain(4) block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) otherBlock := makeBlockWithoutSeal(chain, engine, block) + expectedCommittedSeal := append([]byte{1, 2, 3}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraSeal-3)...) + eventSub := engine.EventMux().Subscribe(istanbul.RequestEvent{}) - eventLoop := func() { + blockOutputChannel := make(chan *types.Block) + stopChannel := make(chan struct{}) + + go func() { select { case ev := <-eventSub.Chan(): - _, ok := ev.Data.(istanbul.RequestEvent) - if !ok { + if _, ok := ev.Data.(istanbul.RequestEvent); !ok { t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) } - engine.Commit(otherBlock, [][]byte{}) + if err := engine.Commit(otherBlock, [][]byte{expectedCommittedSeal}); err != nil { + t.Error(err.Error()) + } } eventSub.Unsubscribe() + }() + + go func() { + if err := engine.Seal(chain, block, blockOutputChannel, stopChannel); err != nil { + t.Error(err.Error()) + } + }() + + select { + case <-blockOutputChannel: + t.Error("Wrong block found!") + default: + //no block found, stop the sealing + close(stopChannel) } - go eventLoop() - seal := func() { - engine.Seal(chain, block, nil, make(chan struct{})) - t.Error("seal should not be completed") - } - go seal() - const timeoutDura = 2 * time.Second - timeout := time.NewTimer(timeoutDura) select { - case <-timeout.C: - // wait 2 seconds to ensure we cannot get any blocks from Istanbul + case output := <-blockOutputChannel: + if output != nil { + t.Error("Block not nil!") + } } } diff --git a/consensus/istanbul/config.go b/consensus/istanbul/config.go index d2d44bf2e8..2a223a1a51 100644 --- a/consensus/istanbul/config.go +++ b/consensus/istanbul/config.go @@ -16,6 +16,8 @@ package istanbul +import "math/big" + type ProposerPolicy uint64 const ( @@ -28,6 +30,7 @@ type Config struct { BlockPeriod uint64 `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second ProposerPolicy ProposerPolicy `toml:",omitempty"` // The policy for proposer selection Epoch uint64 `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes + Ceil2Nby3Block *big.Int `toml:",omitempty"` // Number of confirmations required to move from one state to next [2F + 1 to Ceil(2N/3)] } var DefaultConfig = &Config{ @@ -35,4 +38,5 @@ var DefaultConfig = &Config{ BlockPeriod: 1, ProposerPolicy: RoundRobin, Epoch: 30000, + Ceil2Nby3Block: big.NewInt(0), } diff --git a/consensus/istanbul/core/commit.go b/consensus/istanbul/core/commit.go index fa58102254..166d1925eb 100644 --- a/consensus/istanbul/core/commit.go +++ b/consensus/istanbul/core/commit.go @@ -72,7 +72,7 @@ func (c *core) handleCommit(msg *message, src istanbul.Validator) error { // // If we already have a proposal, we may have chance to speed up the consensus process // by committing the proposal without PREPARE messages. - if c.current.Commits.Size() > 2*c.valSet.F() && c.state.Cmp(StateCommitted) < 0 { + if c.current.Commits.Size() >= c.QuorumSize() && c.state.Cmp(StateCommitted) < 0 { // Still need to call LockHash here since state can skip Prepared state and jump directly to the Committed state. c.current.LockHash() c.commit() diff --git a/consensus/istanbul/core/commit_test.go b/consensus/istanbul/core/commit_test.go index cca5cbbaca..97be7b0622 100644 --- a/consensus/istanbul/core/commit_test.go +++ b/consensus/istanbul/core/commit_test.go @@ -191,8 +191,8 @@ OUTER: if r0.state != StatePrepared { t.Errorf("state mismatch: have %v, want %v", r0.state, StatePrepared) } - if r0.current.Commits.Size() > 2*r0.valSet.F() { - t.Errorf("the size of commit messages should be less than %v", 2*r0.valSet.F()+1) + if r0.current.Commits.Size() >= r0.QuorumSize() { + t.Errorf("the size of commit messages should be less than %v", r0.QuorumSize()) } if r0.current.IsHashLocked() { t.Errorf("block should not be locked") @@ -200,12 +200,12 @@ OUTER: continue } - // core should have 2F+1 prepare messages - if r0.current.Commits.Size() <= 2*r0.valSet.F() { - t.Errorf("the size of commit messages should be larger than 2F+1: size %v", r0.current.Commits.Size()) + // core should have 2F+1 before Ceil2Nby3Block or Ceil(2N/3) prepare messages + if r0.current.Commits.Size() < r0.QuorumSize() { + t.Errorf("the size of commit messages should be larger than 2F+1 or Ceil(2N/3): size %v", r0.QuorumSize()) } - // check signatures large than 2F+1 + // check signatures large than F signedCount := 0 committedSeals := v0.committedMsgs[0].committedSeals for _, validator := range r0.valSet.List() { @@ -216,8 +216,8 @@ OUTER: } } } - if signedCount <= 2*r0.valSet.F() { - t.Errorf("the expected signed count should be larger than %v, but got %v", 2*r0.valSet.F(), signedCount) + if signedCount <= r0.valSet.F() { + t.Errorf("the expected signed count should be larger than %v, but got %v", r0.valSet.F(), signedCount) } if !r0.current.IsHashLocked() { t.Errorf("block should be locked") diff --git a/consensus/istanbul/core/core.go b/consensus/istanbul/core/core.go index c4fd5501b9..a10b5b8f86 100644 --- a/consensus/istanbul/core/core.go +++ b/consensus/istanbul/core/core.go @@ -342,6 +342,15 @@ func (c *core) checkValidatorSignature(data []byte, sig []byte) (common.Address, return istanbul.CheckValidatorSignature(c.valSet, data, sig) } +func (c *core) QuorumSize() int { + if c.config.Ceil2Nby3Block == nil || (c.current != nil && c.current.sequence.Cmp(c.config.Ceil2Nby3Block) < 0) { + c.logger.Trace("Confirmation Formula used 2F+ 1") + return (2 * c.valSet.F()) + 1 + } + c.logger.Trace("Confirmation Formula used ceil(2N/3)") + return int(math.Ceil(float64(2*c.valSet.Size()) / 3)) +} + // PrepareCommittedSeal returns a committed seal for the given hash func PrepareCommittedSeal(hash common.Hash) []byte { var buf bytes.Buffer diff --git a/consensus/istanbul/core/core_test.go b/consensus/istanbul/core/core_test.go index a293ea9eec..e5c753485a 100644 --- a/consensus/istanbul/core/core_test.go +++ b/consensus/istanbul/core/core_test.go @@ -17,6 +17,7 @@ package core import ( + "github.com/ethereum/go-ethereum/common" "math/big" "reflect" "testing" @@ -80,3 +81,20 @@ func TestNewRequest(t *testing.T) { } } } + +func TestQuorumSize(t *testing.T) { + N := uint64(4) + F := uint64(1) + + sys := NewTestSystemWithBackend(N, F) + backend := sys.backends[0] + c := backend.engine.(*core) + + valSet := c.valSet + for i := 1; i <= 1000; i++ { + valSet.AddValidator(common.StringToAddress(string(i))) + if 2*c.QuorumSize() <= (valSet.Size()+valSet.F()) || 2*c.QuorumSize() > (valSet.Size()+valSet.F()+2) { + t.Errorf("quorumSize constraint failed, expected value (2*QuorumSize > Size+F && 2*QuorumSize <= Size+F+2) to be:%v, got: %v, for size: %v", true, false, valSet.Size()) + } + } +} diff --git a/consensus/istanbul/core/errors.go b/consensus/istanbul/core/errors.go index 62a5ce2263..a97353204c 100644 --- a/consensus/istanbul/core/errors.go +++ b/consensus/istanbul/core/errors.go @@ -43,4 +43,6 @@ var ( errFailedDecodeCommit = errors.New("failed to decode COMMIT") // errFailedDecodeMessageSet is returned when the message set is malformed. errFailedDecodeMessageSet = errors.New("failed to decode message set") + // errInvalidSigner is returned when the message is signed by a validator different than message sender + errInvalidSigner = errors.New("message not signed by the sender") ) diff --git a/consensus/istanbul/core/prepare.go b/consensus/istanbul/core/prepare.go index f4ea25ae16..4a1154c06e 100644 --- a/consensus/istanbul/core/prepare.go +++ b/consensus/istanbul/core/prepare.go @@ -59,7 +59,7 @@ func (c *core) handlePrepare(msg *message, src istanbul.Validator) error { // Change to Prepared state if we've received enough PREPARE messages or it is locked // and we are in earlier state before Prepared state. - if ((c.current.IsHashLocked() && prepare.Digest == c.current.GetLockedHash()) || c.current.GetPrepareOrCommitSize() > 2*c.valSet.F()) && + if ((c.current.IsHashLocked() && prepare.Digest == c.current.GetLockedHash()) || c.current.GetPrepareOrCommitSize() >= c.QuorumSize()) && c.state.Cmp(StatePrepared) < 0 { c.current.LockHash() c.setState(StatePrepared) diff --git a/consensus/istanbul/core/prepare_test.go b/consensus/istanbul/core/prepare_test.go index a2b495d85f..ac6ef475c1 100644 --- a/consensus/istanbul/core/prepare_test.go +++ b/consensus/istanbul/core/prepare_test.go @@ -17,6 +17,7 @@ package core import ( + "math" "math/big" "reflect" "testing" @@ -156,12 +157,11 @@ func TestHandlePrepare(t *testing.T) { errInconsistentSubject, }, { - // less than 2F+1 func() *testSystem { sys := NewTestSystemWithBackend(N, F) - // save less than 2*F+1 replica - sys.backends = sys.backends[2*int(F)+1:] + // save less than Ceil(2*N/3) replica + sys.backends = sys.backends[int(math.Ceil(float64(2*N)/3)):] for i, backend := range sys.backends { c := backend.engine.(*core) @@ -214,8 +214,8 @@ OUTER: if r0.state != StatePreprepared { t.Errorf("state mismatch: have %v, want %v", r0.state, StatePreprepared) } - if r0.current.Prepares.Size() > 2*r0.valSet.F() { - t.Errorf("the size of PREPARE messages should be less than %v", 2*r0.valSet.F()+1) + if r0.current.Prepares.Size() >= r0.QuorumSize() { + t.Errorf("the size of PREPARE messages should be less than %v", r0.QuorumSize()) } if r0.current.IsHashLocked() { t.Errorf("block should not be locked") @@ -224,12 +224,12 @@ OUTER: continue } - // core should have 2F+1 PREPARE messages - if r0.current.Prepares.Size() <= 2*r0.valSet.F() { - t.Errorf("the size of PREPARE messages should be larger than 2F+1: size %v", r0.current.Commits.Size()) + // core should have 2F+1 before Ceil2Nby3Block and Ceil(2N/3) after Ceil2Nby3Block PREPARE messages + if r0.current.Prepares.Size() < r0.QuorumSize() { + t.Errorf("the size of PREPARE messages should be larger than 2F+1 or ceil(2N/3): size %v", r0.current.Commits.Size()) } - // a message will be delivered to backend if 2F+1 + // a message will be delivered to backend if ceil(2N/3) if int64(len(v0.sentMsgs)) != 1 { t.Errorf("the Send() should be called once: times %v", len(test.system.backends[0].sentMsgs)) } diff --git a/consensus/istanbul/core/preprepare.go b/consensus/istanbul/core/preprepare.go index a4ee295b7d..9c511062f1 100644 --- a/consensus/istanbul/core/preprepare.go +++ b/consensus/istanbul/core/preprepare.go @@ -82,9 +82,9 @@ func (c *core) handlePreprepare(msg *message, src istanbul.Validator) error { // Verify the proposal we received if duration, err := c.backend.Verify(preprepare.Proposal); err != nil { - logger.Warn("Failed to verify proposal", "err", err, "duration", duration) // if it's a future block, we will handle it again after the duration if err == consensus.ErrFutureBlock { + logger.Info("Proposed block will be handled in the future", "err", err, "duration", duration) c.stopFuturePreprepareTimer() c.futurePreprepareTimer = time.AfterFunc(duration, func() { c.sendEvent(backlogEvent{ @@ -93,6 +93,7 @@ func (c *core) handlePreprepare(msg *message, src istanbul.Validator) error { }) }) } else { + logger.Warn("Failed to verify proposal", "err", err, "duration", duration) c.sendNextRoundChange() } return err diff --git a/consensus/istanbul/core/roundchange.go b/consensus/istanbul/core/roundchange.go index 89ffc41be8..0289ef041b 100644 --- a/consensus/istanbul/core/roundchange.go +++ b/consensus/istanbul/core/roundchange.go @@ -98,8 +98,8 @@ func (c *core) handleRoundChange(msg *message, src istanbul.Validator) error { c.sendRoundChange(roundView.Round) } return nil - } else if num == int(2*c.valSet.F()+1) && (c.waitingForRoundChange || cv.Round.Cmp(roundView.Round) < 0) { - // We've received 2f+1 ROUND CHANGE messages, start a new round immediately. + } else if num == c.QuorumSize() && (c.waitingForRoundChange || cv.Round.Cmp(roundView.Round) < 0) { + // We've received 2f+1/Ceil(2N/3) ROUND CHANGE messages, start a new round immediately. c.startNewRound(roundView.Round) return nil } else if cv.Round.Cmp(roundView.Round) < 0 { diff --git a/consensus/istanbul/core/testbackend_test.go b/consensus/istanbul/core/testbackend_test.go index 812056f1f5..bde93b1cac 100644 --- a/consensus/istanbul/core/testbackend_test.go +++ b/consensus/istanbul/core/testbackend_test.go @@ -109,8 +109,8 @@ func (self *testSystemBackend) Verify(proposal istanbul.Proposal) (time.Duration } func (self *testSystemBackend) Sign(data []byte) ([]byte, error) { - testLogger.Warn("not sign any data") - return data, nil + testLogger.Info("returning current backend address so that CheckValidatorSignature returns the same value") + return self.address.Bytes(), nil } func (self *testSystemBackend) CheckSignature([]byte, common.Address, []byte) error { @@ -118,7 +118,7 @@ func (self *testSystemBackend) CheckSignature([]byte, common.Address, []byte) er } func (self *testSystemBackend) CheckValidatorSignature(data []byte, sig []byte) (common.Address, error) { - return common.Address{}, nil + return common.BytesToAddress(sig), nil } func (self *testSystemBackend) Hash(b interface{}) common.Hash { diff --git a/consensus/istanbul/core/types.go b/consensus/istanbul/core/types.go index da202cb2cd..fca60eb894 100644 --- a/consensus/istanbul/core/types.go +++ b/consensus/istanbul/core/types.go @@ -17,6 +17,7 @@ package core import ( + "bytes" "fmt" "io" @@ -137,10 +138,15 @@ func (m *message) FromPayload(b []byte, validateFn func([]byte, []byte) (common. return err } - _, err = validateFn(payload, m.Signature) + signerAdd, err := validateFn(payload, m.Signature) + if err != nil { + return err + } + if bytes.Compare(signerAdd.Bytes(), m.Address.Bytes()) != 0 { + return errInvalidSigner + } } - // Still return the message even the err is not nil - return err + return nil } func (m *message) Payload() ([]byte, error) { diff --git a/consensus/istanbul/core/types_test.go b/consensus/istanbul/core/types_test.go index a280fba54b..10dcaa8f1d 100644 --- a/consensus/istanbul/core/types_test.go +++ b/consensus/istanbul/core/types_test.go @@ -124,10 +124,11 @@ func testSubjectWithSignature(t *testing.T) { subjectPayload, _ := Encode(s) // 1. Encode test + address := common.HexToAddress("0x1234567890") m := &message{ Code: msgPreprepare, Msg: subjectPayload, - Address: common.HexToAddress("0x1234567890"), + Address: address, Signature: expectedSig, CommittedSeal: []byte{}, } @@ -141,7 +142,7 @@ func testSubjectWithSignature(t *testing.T) { // 2.1 Test normal validate func decodedMsg := new(message) err = decodedMsg.FromPayload(msgPayload, func(data []byte, sig []byte) (common.Address, error) { - return common.Address{}, nil + return address, nil }) if err != nil { t.Errorf("error mismatch: have %v, want nil", err) diff --git a/console/console.go b/console/console.go index 3c397f8006..dd6ccf66d0 100644 --- a/console/console.go +++ b/console/console.go @@ -17,6 +17,7 @@ package console import ( + "context" "fmt" "io" "io/ioutil" @@ -271,17 +272,33 @@ func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, str return line[:start], c.jsre.CompleteKeywords(line[start:pos]), line[pos:] } -// Welcome show summary of current Geth instance and some metadata about the +// Welcome shows a summary of the current Geth instance and some metadata about the // console's available modules. func (c *Console) Welcome() { + consensus := c.getConsensus() + // Print some generic Geth metadata fmt.Fprintf(c.printer, "Welcome to the Geth JavaScript console!\n\n") c.jsre.Run(` - console.log("instance: " + web3.version.node); - console.log("coinbase: " + eth.coinbase); - console.log("at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")"); - console.log(" datadir: " + admin.datadir); - `) + console.log("instance: " + web3.version.node); + console.log("coinbase: " + eth.coinbase); + `) + + // Quorum: Block timestamp for Raft is in nanoseconds, so convert accordingly + if consensus == "raft" { + c.jsre.Run(` + console.log("at block: " + eth.blockNumber + " (" + new Date(eth.getBlock(eth.blockNumber).timestamp / 1000000) + ")"); + `) + } else { + c.jsre.Run(` + console.log("at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")"); + `) + } + + c.jsre.Run(` + console.log(" datadir: " + admin.datadir); + `) + // List all the supported modules for the user to call if apis, err := c.client.SupportedModules(); err == nil { modules := make([]string, 0, len(apis)) @@ -294,6 +311,30 @@ func (c *Console) Welcome() { fmt.Fprintln(c.printer) } +// Get the consensus mechanism that is in use +func (c *Console) getConsensus() string { + + var nodeInfo struct { + Protocols struct { + Eth struct { // only partial of eth/handler.go#NodeInfo + Consensus string + } + Istanbul struct { // a bit different from others + Consensus string + } + } + } + + if err := c.client.CallContext(context.Background(), &nodeInfo, "admin_nodeInfo"); err != nil { + _, _ = fmt.Fprintf(c.printer, "WARNING: call to admin.getNodeInfo() failed, unable to determine consensus mechanism\n") + return "unknown" + } + if nodeInfo.Protocols.Istanbul.Consensus != "" { + return nodeInfo.Protocols.Istanbul.Consensus + } + return nodeInfo.Protocols.Eth.Consensus +} + // Evaluate executes code and pretty prints the result to the specified output // stream. func (c *Console) Evaluate(statement string) error { diff --git a/core/blockchain.go b/core/blockchain.go index ee9feb6a83..4cffd7d7c6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1149,6 +1149,12 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty // If the chain is terminating, stop processing blocks if atomic.LoadInt32(&bc.procInterrupt) == 1 { log.Debug("Premature abort during blocks processing") + // QUORUM + if bc.chainConfig.IsQuorum && bc.chainConfig.Istanbul == nil && bc.chainConfig.Clique == nil { + // Only returns an error for raft mode + return i, events, coalescedLogs, ErrAbortBlocksProcessing + } + // END QUORUM break } // If the header is a banned one, straight out abort @@ -1271,9 +1277,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty if err := WritePrivateStateRoot(bc.db, block.Root(), privateStateRoot); err != nil { return i, events, coalescedLogs, err } - // /Quorum - allReceipts := mergeReceipts(receipts, privateReceipts) + // /Quorum proctime := time.Since(bstart) diff --git a/core/call_helper.go b/core/call_helper.go index 60960e00f9..0cb17aea55 100644 --- a/core/call_helper.go +++ b/core/call_helper.go @@ -47,7 +47,12 @@ func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Ad cg.header.GasLimit = 4700000 signer := types.MakeSigner(params.QuorumTestChainConfig, cg.header.Number) + if private { + signer = types.QuorumPrivateTxSigner{} + } + tx, err := types.SignTx(types.NewTransaction(cg.TxNonce(from), to, new(big.Int), 1000000, new(big.Int), input), signer, key) + if err != nil { return err } @@ -60,15 +65,13 @@ func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Ad publicState, privateState := cg.PublicState, cg.PrivateState if !private { privateState = publicState - } else { - tx.SetPrivate() } - // TODO(joel): can we just pass nil instead of bc? bc, _ := NewBlockChain(cg.db, nil, params.QuorumTestChainConfig, ethash.NewFaker(), vm.Config{}, nil) context := NewEVMContext(msg, &cg.header, bc, &from) vmenv := vm.NewEVM(context, publicState, privateState, params.QuorumTestChainConfig, vm.Config{}) - _, _, _, err = ApplyMessage(vmenv, msg, cg.gp) + sender := vm.AccountRef(msg.From()) + vmenv.Call(sender, to, msg.Data(), 100000000, new(big.Int)) if err != nil { return err } diff --git a/core/database_util.go b/core/database_util.go index a2766030cd..bca4562262 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -675,5 +675,3 @@ func GetPrivateBlockBloom(db ethdb.Database, number uint64) (bloom types.Bloom) } return bloom } - - diff --git a/core/error.go b/core/error.go index 410eca1e1e..086c448e08 100644 --- a/core/error.go +++ b/core/error.go @@ -32,4 +32,7 @@ var ( // ErrNonceTooHigh is returned if the nonce of a transaction is higher than the // next one expected based on the local chain. ErrNonceTooHigh = errors.New("nonce too high") + + // ErrAbortBlocksProcessing is returned if bc.insertChain is interrupted under raft mode + ErrAbortBlocksProcessing = errors.New("abort during blocks processing") ) diff --git a/core/genesis.go b/core/genesis.go index 56b88b7611..9b5a373fa7 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 d353b3866f..c4621731df 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -24,6 +24,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" + //"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core/rawdb" //"github.com/ethereum/go-ethereum/core/vm" @@ -90,11 +91,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/private_state_test.go b/core/private_state_test.go index eeeb131df9..7d7129eb87 100644 --- a/core/private_state_test.go +++ b/core/private_state_test.go @@ -20,7 +20,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/private" - "github.com/ethereum/go-ethereum/private/constellation" + "github.com/ethereum/go-ethereum/private/privatetransactionmanager" ) // callmsg is the message type used for call transactions in the private state test @@ -128,7 +128,7 @@ func runConstellation() (*osExec.Cmd, error) { if constellationErr != nil { return nil, constellationErr } - private.P = constellation.MustNew(cfgFile.Name()) + private.P = privatetransactionmanager.MustNew(cfgFile.Name()) return constellationCmd, nil } @@ -263,13 +263,15 @@ func runTessera() (*osExec.Cmd, error) { } // 600a600055600060006001a1 -// [1] PUSH1 0x0a (store value) -// [3] PUSH1 0x00 (store addr) -// [4] SSTORE -// [6] PUSH1 0x00 -// [8] PUSH1 0x00 -// [10] PUSH1 0x01 -// [11] LOG1 +// 60 0a, 60 00, 55, 60 00, 60 00, 60 01, a1 +// [1] (0x60) PUSH1 0x0a (store value) +// [3] (0x60) PUSH1 0x00 (store addr) +// [4] (0x55) SSTORE (Store (k-00,v-a)) + +// [6] (0x60) PUSH1 0x00 +// [8] (0x60) PUSH1 0x00 +// [10](0x60) PUSH1 0x01 +// [11](0xa1) LOG1 offset(0x01), len(0x00), topic(0x00) // // Store then log func TestPrivateTransaction(t *testing.T) { @@ -294,10 +296,12 @@ func TestPrivateTransaction(t *testing.T) { prvContractAddr := common.Address{1} pubContractAddr := common.Address{2} + // SSTORE (K,V) SSTORE(0, 10): 600a600055 + // + + // LOG1 OFFSET LEN TOPIC, LOG1 (a1) 01, 00, 00: 600060006001a1 privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a600055600060006001a1")) - privateState.SetState(prvContractAddr, common.Hash{}, common.Hash{9}) + // SSTORE (K,V) SSTORE(0, 14): 6014600055 publicState.SetCode(pubContractAddr, common.Hex2Bytes("6014600055")) - publicState.SetState(pubContractAddr, common.Hash{}, common.Hash{19}) if publicState.Exist(prvContractAddr) { t.Error("didn't expect private contract address to exist on public state") @@ -305,6 +309,7 @@ func TestPrivateTransaction(t *testing.T) { // Private transaction 1 err = helper.MakeCall(true, key, prvContractAddr, nil) + if err != nil { t.Fatal(err) } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index f7586b70d0..db4a721328 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -119,7 +119,7 @@ func TestIntermediateLeaks(t *testing.T) { func TestStorageRoot(t *testing.T) { var ( - mem = ethdb.NewMemDatabase() + mem = ethdb.NewMemDatabase() db = NewDatabase(mem) state, _ = New(common.Hash{}, db) addr = common.Address{1} diff --git a/core/state_transition.go b/core/state_transition.go index 89166dda0a..3ab528488b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -188,6 +188,12 @@ func (st *StateTransition) preCheck() error { // TransitionDb will transition the state by applying the current message and // returning the result including the used gas. It returns an error if failed. // An error indicates a consensus issue. +// +// Quorum: +// 1. Intrinsic gas is calculated based on the encrypted payload hash +// and NOT the actual private payload +// 2. For private transactions, we only deduct intrinsic gas from the gas pool +// regardless the current node is party to the transaction or not func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) { if err = st.preCheck(); err != nil { return @@ -231,7 +237,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo var ( leftoverGas uint64 - evm = st.evm + evm = st.evm // vm errors do not effect consensus and are therefor // not assigned to err, except for insufficient balance // error. @@ -254,6 +260,8 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo } //if input is empty for the smart contract call, return if len(data) == 0 && isPrivate { + st.refundGas() + st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) return nil, 0, false, nil } diff --git a/core/state_transition_test.go b/core/state_transition_test.go new file mode 100644 index 0000000000..06d5635409 --- /dev/null +++ b/core/state_transition_test.go @@ -0,0 +1,115 @@ +package core + +import ( + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/private" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" + + testifyassert "github.com/stretchr/testify/assert" +) + +func verifyGasPoolCalculation(t *testing.T, pm private.PrivateTransactionManager) { + assert := testifyassert.New(t) + saved := private.P + defer func() { + private.P = saved + }() + private.P = pm + + txGasLimit := uint64(100000) + gasPool := new(GasPool).AddGas(200000) + // this payload would give us 25288 intrinsic gas + arbitraryEncryptedPayload := "4ab80888354582b92ab442a317828386e4bf21ea4a38d1a9183fbb715f199475269d7686939017f4a6b28310d5003ebd8e012eade530b79e157657ce8dd9692a" + expectedGasPool := new(GasPool).AddGas(174712) // only intrinsic gas is deducted + + db := ethdb.NewMemDatabase() + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db)) + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db)) + msg := privateCallMsg{ + callmsg: callmsg{ + addr: common.Address{2}, + to: &common.Address{}, + value: new(big.Int), + gas: txGasLimit, + gasPrice: big.NewInt(0), + data: common.Hex2Bytes(arbitraryEncryptedPayload), + }, + } + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &common.Address{}) + evm := vm.NewEVM(ctx, publicState, privateState, params.QuorumTestChainConfig, vm.Config{}) + arbitraryBalance := big.NewInt(100000000) + publicState.SetBalance(evm.Coinbase, arbitraryBalance) + publicState.SetBalance(msg.From(), arbitraryBalance) + + testObject := NewStateTransition(evm, msg, gasPool) + + _, _, failed, err := testObject.TransitionDb() + + assert.NoError(err) + assert.False(failed) + + assert.Equal(new(big.Int).SetUint64(expectedGasPool.Gas()), new(big.Int).SetUint64(gasPool.Gas()), "gas pool must be calculated correctly") + assert.Equal(arbitraryBalance, publicState.GetBalance(evm.Coinbase), "balance must not be changed") + assert.Equal(arbitraryBalance, publicState.GetBalance(msg.From()), "balance must not be changed") +} + +func TestStateTransition_TransitionDb_GasPoolCalculation_whenNonPartyNodeProcessingPrivateTransactions(t *testing.T) { + stubPTM := &StubPrivateTransactionManager{ + responses: map[string][]interface{}{ + "Receive": { + []byte{}, + nil, + }, + }, + } + verifyGasPoolCalculation(t, stubPTM) +} + +func TestStateTransition_TransitionDb_GasPoolCalculation_whenPartyNodeProcessingPrivateTransactions(t *testing.T) { + stubPTM := &StubPrivateTransactionManager{ + responses: map[string][]interface{}{ + "Receive": { + common.Hex2Bytes("600a6000526001601ff300"), + nil, + }, + }, + } + verifyGasPoolCalculation(t, stubPTM) +} + +type privateCallMsg struct { + callmsg +} + +func (pm privateCallMsg) IsPrivate() bool { return true } + +type StubPrivateTransactionManager struct { + responses map[string][]interface{} +} + +func (spm *StubPrivateTransactionManager) Send(data []byte, from string, to []string) ([]byte, error) { + return nil, fmt.Errorf("to be implemented") +} + +func (spm *StubPrivateTransactionManager) SendSignedTx(data []byte, to []string) ([]byte, error) { + return nil, fmt.Errorf("to be implemented") +} + +func (spm *StubPrivateTransactionManager) Receive(data []byte) ([]byte, error) { + res := spm.responses["Receive"] + if err, ok := res[1].(error); ok { + return nil, err + } + if ret, ok := res[0].([]byte); ok { + return ret, nil + } + return nil, nil +} diff --git a/core/tx_pool.go b/core/tx_pool.go index 2b4f7a51a6..2395306a21 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, @@ -628,6 +630,14 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if tx.Gas() < intrGas { return ErrIntrinsicGas } + + // Check if the sender account is authorized to perform the transaction + if isQuorum { + if err := checkAccount(from, tx.To()); err != nil { + return err + } + } + return nil } @@ -1293,3 +1303,28 @@ func (t *txLookup) Remove(hash common.Hash) { delete(t.all, hash) } + +// checks if the account is has the necessary access for the transaction +func checkAccount(fromAcct common.Address, toAcct *common.Address) error { + access := types.GetAcctAccess(fromAcct) + + switch access { + case types.ReadOnly: + return errors.New("read only account. cannot transact") + + case types.Transact: + if toAcct == nil { + return errors.New("account does not have contract create permissions") + } + + case types.FullAccess, types.ContractDeploy: + return nil + + } + return nil +} + +// helper function to return chainHeadChannel size +func GetChainHeadChannleSize() int { + return chainHeadChanSize +} diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 0048ff4ae4..8ae210ae59 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -139,7 +139,7 @@ func validateEvents(events chan NewTxsEvent, count int) error { case ev := <-events: received = append(received, ev.Txs...) case <-time.After(time.Second): - return fmt.Errorf("event #%d not fired", received) + return fmt.Errorf("event #%d not fired", len(received)) } } if len(received) > count { diff --git a/core/types/permissions_cache.go b/core/types/permissions_cache.go new file mode 100644 index 0000000000..f0e8a2823d --- /dev/null +++ b/core/types/permissions_cache.go @@ -0,0 +1,421 @@ +package types + +import ( + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/p2p/enode" + + "github.com/ethereum/go-ethereum/common" + lru "github.com/hashicorp/golang-lru" +) + +type AccessType uint8 + +const ( + ReadOnly AccessType = iota + Transact + ContractDeploy + FullAccess +) + +type OrgStatus uint8 + +const ( + OrgPendingApproval OrgStatus = iota + 1 + OrgApproved + OrgPendingSuspension + OrgSuspended +) + +type OrgInfo struct { + OrgId string `json:"orgId"` + FullOrgId string `json:"fullOrgId"` + ParentOrgId string `json:"parentOrgId"` + UltimateParent string `json:"ultimateParent"` + Level *big.Int `json:"level"` + SubOrgList []string `json:"subOrgList"` + Status OrgStatus `json:"status"` +} + +type NodeStatus uint8 + +const ( + NodePendingApproval NodeStatus = iota + 1 + NodeApproved + NodeDeactivated + NodeBlackListed + NodeRecoveryInitiated +) + +type AcctStatus uint8 + +const ( + AcctPendingApproval AcctStatus = iota + 1 + AcctActive + AcctInactive + AcctSuspended + AcctBlacklisted + AdminRevoked + AcctRecoveryInitiated + AcctRecoveryCompleted +) + +type NodeInfo struct { + OrgId string `json:"orgId"` + Url string `json:"url"` + Status NodeStatus `json:"status"` +} + +type RoleInfo struct { + OrgId string `json:"orgId"` + RoleId string `json:"roleId"` + IsVoter bool `json:"isVoter"` + IsAdmin bool `json:"isAdmin"` + Access AccessType `json:"access"` + Active bool `json:"active"` +} + +type AccountInfo struct { + OrgId string `json:"orgId"` + RoleId string `json:"roleId"` + AcctId common.Address `json:"acctId"` + IsOrgAdmin bool `json:"isOrgAdmin"` + Status AcctStatus `json:"status"` +} + +type OrgDetailInfo struct { + NodeList []NodeInfo `json:"nodeList"` + RoleList []RoleInfo `json:"roleList"` + AcctList []AccountInfo `json:"acctList"` + SubOrgList []string `json:"subOrgList"` +} + +// permission config for bootstrapping +type PermissionConfig struct { + UpgrdAddress common.Address `json:"upgrdableAddress"` + InterfAddress common.Address `json:"interfaceAddress"` + ImplAddress common.Address `json:"implAddress"` + NodeAddress common.Address `json:"nodeMgrAddress"` + AccountAddress common.Address `json:"accountMgrAddress"` + RoleAddress common.Address `json:"roleMgrAddress"` + VoterAddress common.Address `json:"voterMgrAddress"` + OrgAddress common.Address `json:"orgMgrAddress"` + NwAdminOrg string `json:"nwAdminOrg"` + NwAdminRole string `json:"nwAdminRole"` + OrgAdminRole string `json:"orgAdminRole"` + + Accounts []common.Address `json:"accounts"` //initial list of account that need full access + SubOrgDepth *big.Int `json:"subOrgDepth"` + SubOrgBreadth *big.Int `json:"subOrgBreadth"` +} + +type OrgKey struct { + OrgId string +} + +type NodeKey struct { + OrgId string + Url string +} + +type RoleKey struct { + OrgId string + RoleId string +} + +type AccountKey struct { + AcctId common.Address +} + +type OrgCache struct { + c *lru.Cache + mux sync.Mutex +} + +type NodeCache struct { + c *lru.Cache +} + +type RoleCache struct { + c *lru.Cache +} + +type AcctCache struct { + c *lru.Cache +} + +func NewOrgCache() *OrgCache { + c, _ := lru.New(defaultOrgMapLimit) + return &OrgCache{c, sync.Mutex{}} +} + +func NewNodeCache() *NodeCache { + c, _ := lru.New(defaultNodeMapLimit) + return &NodeCache{c} +} + +func NewRoleCache() *RoleCache { + c, _ := lru.New(defaultRoleMapLimit) + return &RoleCache{c} +} + +func NewAcctCache() *AcctCache { + c, _ := lru.New(defaultAccountMapLimit) + return &AcctCache{c} +} + +var syncStarted = false + +var DefaultAccess = FullAccess +var QIP714BlockReached = false +var networkAdminRole string +var orgAdminRole string + +const defaultOrgMapLimit = 2000 +const defaultRoleMapLimit = 2500 +const defaultNodeMapLimit = 1000 +const defaultAccountMapLimit = 6000 + +var OrgInfoMap = NewOrgCache() +var NodeInfoMap = NewNodeCache() +var RoleInfoMap = NewRoleCache() +var AcctInfoMap = NewAcctCache() + +func (pc *PermissionConfig) IsEmpty() bool { + return pc.InterfAddress == common.HexToAddress("0x0") +} + +func SetSyncStatus() { + syncStarted = true +} + +func GetSyncStatus() bool { + return syncStarted +} + +// sets the default access to Readonly upon QIP714Blokc +func SetDefaultAccess(){ + DefaultAccess = ReadOnly + QIP714BlockReached = true +} + +// sets default access to readonly and initializes the values for +// network admin role and org admin role +func SetDefaults(nwRoleId, oaRoleId string) { + networkAdminRole = nwRoleId + orgAdminRole = oaRoleId +} + +func GetDefaults() (string, string, AccessType) { + return networkAdminRole, orgAdminRole, DefaultAccess +} + +func (o *OrgCache) UpsertOrg(orgId, parentOrg, ultimateParent string, level *big.Int, status OrgStatus) { + defer o.mux.Unlock() + o.mux.Lock() + var key OrgKey + if parentOrg == "" { + key = OrgKey{OrgId: orgId} + } else { + key = OrgKey{OrgId: parentOrg + "." + orgId} + pkey := OrgKey{OrgId: parentOrg} + if ent, ok := o.c.Get(pkey); ok { + porg := ent.(*OrgInfo) + if !containsKey(porg.SubOrgList, key.OrgId) { + porg.SubOrgList = append(porg.SubOrgList, key.OrgId) + o.c.Add(pkey, porg) + } + } + } + + norg := &OrgInfo{orgId, key.OrgId, parentOrg, ultimateParent, level, nil, status} + o.c.Add(key, norg) +} + +func containsKey(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} + +func (o *OrgCache) GetOrg(orgId string) *OrgInfo { + defer o.mux.Unlock() + o.mux.Lock() + key := OrgKey{OrgId: orgId} + if ent, ok := o.c.Get(key); ok { + return ent.(*OrgInfo) + } + return nil +} + +func (o *OrgCache) GetOrgList() []OrgInfo { + olist := make([]OrgInfo, len(o.c.Keys())) + for i, k := range o.c.Keys() { + v, _ := o.c.Get(k) + vp := v.(*OrgInfo) + olist[i] = *vp + } + return olist +} + +func (n *NodeCache) UpsertNode(orgId string, url string, status NodeStatus) { + key := NodeKey{OrgId: orgId, Url: url} + n.c.Add(key, &NodeInfo{orgId, url, status}) +} + +func (n *NodeCache) GetNodeByUrl(url string) *NodeInfo { + for _, k := range n.c.Keys() { + ent := k.(NodeKey) + if ent.Url == url { + v, _ := n.c.Get(ent) + return v.(*NodeInfo) + } + } + return nil +} + +func (n *NodeCache) GetNodeList() []NodeInfo { + olist := make([]NodeInfo, len(n.c.Keys())) + for i, k := range n.c.Keys() { + v, _ := n.c.Get(k) + vp := v.(*NodeInfo) + olist[i] = *vp + } + return olist +} + +func (a *AcctCache) UpsertAccount(orgId string, role string, acct common.Address, orgAdmin bool, status AcctStatus) { + key := AccountKey{acct} + a.c.Add(key, &AccountInfo{orgId, role, acct, orgAdmin, status}) +} + +func (a *AcctCache) GetAccount(acct common.Address) *AccountInfo { + if v, ok := a.c.Get(AccountKey{acct}); ok { + return v.(*AccountInfo) + } + return nil +} + +func (a *AcctCache) GetAcctList() []AccountInfo { + alist := make([]AccountInfo, len(a.c.Keys())) + for i, k := range a.c.Keys() { + v, _ := a.c.Get(k) + vp := v.(*AccountInfo) + alist[i] = *vp + } + return alist +} + +func (a *AcctCache) GetAcctListOrg(orgId string) []AccountInfo { + var alist []AccountInfo + for _, k := range a.c.Keys() { + v, _ := a.c.Get(k) + vp := v.(*AccountInfo) + if vp.OrgId == orgId { + alist = append(alist, *vp) + } + } + return alist +} + +func (a *AcctCache) GetAcctListRole(orgId, roleId string) []AccountInfo { + var alist []AccountInfo + for _, k := range a.c.Keys() { + v, _ := a.c.Get(k) + vp := v.(*AccountInfo) + + if vp.RoleId == roleId && (vp.OrgId == orgId || OrgInfoMap.GetOrg(vp.OrgId).UltimateParent == orgId) { + alist = append(alist, *vp) + } + } + return alist +} + +func (r *RoleCache) UpsertRole(orgId string, role string, voter bool, admin bool, access AccessType, active bool) { + key := RoleKey{orgId, role} + r.c.Add(key, &RoleInfo{orgId, role, voter, admin, access, active}) + +} + +func (r *RoleCache) GetRole(orgId string, roleId string) *RoleInfo { + key := RoleKey{OrgId: orgId, RoleId: roleId} + if ent, ok := r.c.Get(key); ok { + return ent.(*RoleInfo) + } + return nil +} + +func (r *RoleCache) GetRoleList() []RoleInfo { + rlist := make([]RoleInfo, len(r.c.Keys())) + for i, k := range r.c.Keys() { + v, _ := r.c.Get(k) + vp := v.(*RoleInfo) + rlist[i] = *vp + } + return rlist +} + +// Returns the access type for an account. If not found returns +// default access +func GetAcctAccess(acctId common.Address) AccessType { + //if we have not reached QIP714 block return default access + //which will be full access + if !QIP714BlockReached { + return DefaultAccess + } + + // check if the org status is fine to do the transaction + a := AcctInfoMap.GetAccount(acctId) + if a != nil && a.Status == AcctActive { + // get the org details and ultimate org details. check org status + // if the org is not approved or pending suspension + o := OrgInfoMap.GetOrg(a.OrgId) + if o != nil && (o.Status == OrgApproved || o.Status == OrgPendingSuspension) { + u := OrgInfoMap.GetOrg(o.UltimateParent) + if u != nil && (u.Status == OrgApproved || u.Status == OrgPendingSuspension) { + if a.RoleId == networkAdminRole || a.RoleId == orgAdminRole { + return FullAccess + } + if r := RoleInfoMap.GetRole(a.OrgId, a.RoleId); r != nil && r.Active { + return r.Access + } + if r := RoleInfoMap.GetRole(o.UltimateParent, a.RoleId); r != nil && r.Active { + return r.Access + } + } + } + } + return DefaultAccess +} + +func ValidateNodeForTxn(hexnodeId string, from common.Address) bool { + if !QIP714BlockReached || hexnodeId == ""{ + return true + } + + passedEnodeId, err := enode.ParseV4(hexnodeId) + if err != nil { + return false + } + + ac := AcctInfoMap.GetAccount(from) + if ac == nil { + return true + } + + ultimateParent := OrgInfoMap.GetOrg(ac.OrgId).UltimateParent + // scan through the node list and validate + for _, n := range NodeInfoMap.GetNodeList() { + if OrgInfoMap.GetOrg(n.OrgId).UltimateParent == ultimateParent { + recEnodeId, _ := enode.ParseV4(n.Url) + if recEnodeId.ID() == passedEnodeId.ID() { + return true + } + } + } + return false +} diff --git a/core/types/permissions_cache_test.go b/core/types/permissions_cache_test.go new file mode 100644 index 0000000000..47df8430b5 --- /dev/null +++ b/core/types/permissions_cache_test.go @@ -0,0 +1,244 @@ +package types + +import ( + "fmt" + "math/big" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + testifyassert "github.com/stretchr/testify/assert" +) + +var ( + NETWORKADMIN = "NWADMIN" + ORGADMIN = "OADMIN" + NODE1 = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@127.0.0.1:21000?discport=0&raftport=50401" + NODE2 = "enode://0ba6b9f606a43a95edc6247cdb1c1e105145817be7bcafd6b2c0ba15d58145f0dc1a194f70ba73cd6f4cdd6864edc7687f311254c7555cc32e4d45aeb1b80416@127.0.0.1:21001?discport=0&raftport=50402" +) + +var Acct1 = common.BytesToAddress([]byte("permission")) +var Acct2 = common.BytesToAddress([]byte("perm-test")) + +func TestSetSyncStatus(t *testing.T) { + assert := testifyassert.New(t) + + SetSyncStatus() + + // check if the value is set properly by calling Get + syncStatus := GetSyncStatus() + assert.True(syncStatus == true, fmt.Sprintf("Expected syncstatus %v . Got %v ", true, syncStatus)) +} + +func TestSetDefaults(t *testing.T) { + assert := testifyassert.New(t) + + SetDefaults(NETWORKADMIN, ORGADMIN) + + // get the default values and confirm the same + networkAdminRole, orgAdminRole, defaultAccess := GetDefaults() + + assert.True(networkAdminRole == NETWORKADMIN, fmt.Sprintf("Expected network admin role %v, got %v", NETWORKADMIN, networkAdminRole)) + assert.True(orgAdminRole == ORGADMIN, fmt.Sprintf("Expected network admin role %v, got %v", ORGADMIN, orgAdminRole)) + assert.True(defaultAccess == FullAccess, fmt.Sprintf("Expected network admin role %v, got %v", FullAccess, defaultAccess)) + + SetDefaultAccess() + networkAdminRole, orgAdminRole, defaultAccess = GetDefaults() + assert.True(defaultAccess == ReadOnly, fmt.Sprintf("Expected network admin role %v, got %v", ReadOnly, defaultAccess)) +} + +func TestOrgCache_UpsertOrg(t *testing.T) { + assert := testifyassert.New(t) + + //add a org and get the org details + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + orgInfo := OrgInfoMap.GetOrg(NETWORKADMIN) + + assert.False(orgInfo == nil, fmt.Sprintf("Expected org details, got nil")) + assert.True(orgInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id %v, got %v", NETWORKADMIN, orgInfo.OrgId)) + + // update org status to suspended + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgSuspended) + orgInfo = OrgInfoMap.GetOrg(NETWORKADMIN) + + assert.True(orgInfo.Status == OrgSuspended, fmt.Sprintf("Expected org status %v, got %v", OrgSuspended, orgInfo.Status)) + + //add another org and check get org list + OrgInfoMap.UpsertOrg(ORGADMIN, "", ORGADMIN, big.NewInt(1), OrgApproved) + orgList := OrgInfoMap.GetOrgList() + assert.True(len(orgList) == 2, fmt.Sprintf("Expected 2 entries, got %v", len(orgList))) + + //add sub org and check get orglist + OrgInfoMap.UpsertOrg("SUB1", ORGADMIN, ORGADMIN, big.NewInt(2), OrgApproved) + orgList = OrgInfoMap.GetOrgList() + assert.True(len(orgList) == 3, fmt.Sprintf("Expected 3 entries, got %v", len(orgList))) + + //suspend the sub org and check get orglist + OrgInfoMap.UpsertOrg("SUB1", ORGADMIN, ORGADMIN, big.NewInt(2), OrgSuspended) + orgList = OrgInfoMap.GetOrgList() + assert.True(len(orgList) == 3, fmt.Sprintf("Expected 3 entries, got %v", len(orgList))) +} + +func TestNodeCache_UpsertNode(t *testing.T) { + assert := testifyassert.New(t) + + // add a node into the cache and validate + NodeInfoMap.UpsertNode(NETWORKADMIN, NODE1, NodeApproved) + nodeInfo := NodeInfoMap.GetNodeByUrl(NODE1) + assert.False(nodeInfo == nil, fmt.Sprintf("Expected node details, got nil")) + assert.True(nodeInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for node %v, got %v", NETWORKADMIN, nodeInfo.OrgId)) + assert.True(nodeInfo.Url == NODE1, fmt.Sprintf("Expected node id %v, got %v", NODE1, nodeInfo.Url)) + + // add another node and validate the list function + NodeInfoMap.UpsertNode(ORGADMIN, NODE2, NodeApproved) + nodeList := NodeInfoMap.GetNodeList() + assert.True(len(nodeList) == 2, fmt.Sprintf("Expected 2 entries, got %v", len(nodeList))) + + // check node details update by updating node status + NodeInfoMap.UpsertNode(ORGADMIN, NODE2, NodeDeactivated) + nodeInfo = NodeInfoMap.GetNodeByUrl(NODE2) + assert.True(nodeInfo.Status == NodeDeactivated, fmt.Sprintf("Expected node status %v, got %v", NodeDeactivated, nodeInfo.Status)) +} + +func TestRoleCache_UpsertRole(t *testing.T) { + assert := testifyassert.New(t) + + // add a role into the cache and validate + RoleInfoMap.UpsertRole(NETWORKADMIN, NETWORKADMIN, true, true, FullAccess, true) + roleInfo := RoleInfoMap.GetRole(NETWORKADMIN, NETWORKADMIN) + assert.False(roleInfo == nil, fmt.Sprintf("Expected role details, got nil")) + assert.True(roleInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for node %v, got %v", NETWORKADMIN, roleInfo.OrgId)) + assert.True(roleInfo.RoleId == NETWORKADMIN, fmt.Sprintf("Expected node id %v, got %v", NETWORKADMIN, roleInfo.RoleId)) + + // add another role and validate the list function + RoleInfoMap.UpsertRole(ORGADMIN, ORGADMIN, true, true, FullAccess, true) + roleList := RoleInfoMap.GetRoleList() + assert.True(len(roleList) == 2, fmt.Sprintf("Expected 2 entries, got %v", len(roleList))) + + // update role status and validate + RoleInfoMap.UpsertRole(ORGADMIN, ORGADMIN, true, true, FullAccess, false) + roleInfo = RoleInfoMap.GetRole(ORGADMIN, ORGADMIN) + assert.True(roleInfo.Active == false, fmt.Sprintf("Expected role active status to be %v, got %v", true, roleInfo.Active)) +} + +func TestAcctCache_UpsertAccount(t *testing.T) { + assert := testifyassert.New(t) + + // add an account into the cache and validate + AcctInfoMap.UpsertAccount(NETWORKADMIN, NETWORKADMIN, Acct1, true, AcctActive) + acctInfo := AcctInfoMap.GetAccount(Acct1) + assert.False(acctInfo == nil, fmt.Sprintf("Expected account details, got nil")) + assert.True(acctInfo.OrgId == NETWORKADMIN, fmt.Sprintf("Expected org id for the account to be %v, got %v", NETWORKADMIN, acctInfo.OrgId)) + assert.True(acctInfo.AcctId == Acct1, fmt.Sprintf("Expected account id %x, got %x", Acct1, acctInfo.AcctId)) + + // add a second account and validate the list function + AcctInfoMap.UpsertAccount(ORGADMIN, ORGADMIN, Acct2, true, AcctActive) + acctList := AcctInfoMap.GetAcctList() + assert.True(len(acctList) == 2, fmt.Sprintf("Expected 2 entries, got %v", len(acctList))) + + // update account status and validate + AcctInfoMap.UpsertAccount(ORGADMIN, ORGADMIN, Acct2, true, AcctBlacklisted) + acctInfo = AcctInfoMap.GetAccount(Acct2) + assert.True(acctInfo.Status == AcctBlacklisted, fmt.Sprintf("Expected account status to be %v, got %v", AcctBlacklisted, acctInfo.Status)) + + // validate the list for org and role functions + acctList = AcctInfoMap.GetAcctListOrg(NETWORKADMIN) + assert.True(len(acctList) == 1, fmt.Sprintf("Expected number of accounts for the org to be 1, got %v", len(acctList))) + acctList = AcctInfoMap.GetAcctListRole(NETWORKADMIN, NETWORKADMIN) + assert.True(len(acctList) == 1, fmt.Sprintf("Expected number of accounts for the role to be 1, got %v", len(acctList))) +} + +func TestGetAcctAccess(t *testing.T) { + assert := testifyassert.New(t) + + // default access when the cache is not populated, should return default access + SetDefaults(NETWORKADMIN, ORGADMIN) + SetDefaultAccess() + access := GetAcctAccess(Acct1) + assert.True(access == ReadOnly, fmt.Sprintf("Expected account access to be %v, got %v", ReadOnly, access)) + + // Create an org with two roles and two accounts linked to different roles. Validate account access + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + RoleInfoMap.UpsertRole(NETWORKADMIN, NETWORKADMIN, true, true, FullAccess, true) + RoleInfoMap.UpsertRole(NETWORKADMIN, "ROLE1", true, true, FullAccess, true) + AcctInfoMap.UpsertAccount(NETWORKADMIN, NETWORKADMIN, Acct1, true, AcctActive) + AcctInfoMap.UpsertAccount(NETWORKADMIN, "ROLE1", Acct2, true, AcctActive) + + access = GetAcctAccess(Acct1) + assert.True(access == FullAccess, fmt.Sprintf("Expected account access to be %v, got %v", FullAccess, access)) + + // mark the org as pending suspension. The account access should not change + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgPendingSuspension) + access = GetAcctAccess(Acct1) + assert.True(access == FullAccess, fmt.Sprintf("Expected account access to be %v, got %v", FullAccess, access)) + + // suspend the org and the account access should be readonly now + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgSuspended) + access = GetAcctAccess(Acct1) + assert.True(access == ReadOnly, fmt.Sprintf("Expected account access to be %v, got %v", ReadOnly, access)) + + // mark the role as inactive and account access should now nbe read only + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + RoleInfoMap.UpsertRole(NETWORKADMIN, "ROLE1", true, true, FullAccess, false) + access = GetAcctAccess(Acct2) + assert.True(access == ReadOnly, fmt.Sprintf("Expected account access to be %v, got %v", ReadOnly, access)) +} + +func TestValidateNodeForTxn(t *testing.T) { + assert := testifyassert.New(t) + // pass the enode as null and the response should be true + txnAllowed := ValidateNodeForTxn("", Acct1) + assert.True(txnAllowed == true, "Expected access %v, got %v", true, txnAllowed) + + SetDefaultAccess() + + // if a proper enode id is not passed, return should be false + txnAllowed = ValidateNodeForTxn("ABCDE", Acct1) + assert.True(txnAllowed == false, "Expected access %v, got %v", true, txnAllowed) + + // if cache is not populated but the enode and account details are proper, + // should return true + txnAllowed = ValidateNodeForTxn(NODE1, Acct1) + assert.True(txnAllowed == true, "Expected access %v, got %v", true, txnAllowed) + + // populate an org, account and node. validate access + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + NodeInfoMap.UpsertNode(NETWORKADMIN, NODE1, NodeApproved) + AcctInfoMap.UpsertAccount(NETWORKADMIN, NETWORKADMIN, Acct1, true, AcctActive) + txnAllowed = ValidateNodeForTxn(NODE1, Acct1) + assert.True(txnAllowed == true, "Expected access %v, got %v", true, txnAllowed) + + // test access from a node not linked to the org. should return false + OrgInfoMap.UpsertOrg(ORGADMIN, "", ORGADMIN, big.NewInt(1), OrgApproved) + NodeInfoMap.UpsertNode(ORGADMIN, NODE2, NodeApproved) + AcctInfoMap.UpsertAccount(ORGADMIN, ORGADMIN, Acct2, true, AcctActive) + txnAllowed = ValidateNodeForTxn(NODE1, Acct2) + assert.True(txnAllowed == false, "Expected access %v, got %v", true, txnAllowed) +} + +// This is to make sure enode.ParseV4() honors single hexNodeId value eventhough it does follow enode URI scheme +func TestValidateNodeForTxn_whenUsingOnlyHexNodeId(t *testing.T) { + OrgInfoMap.UpsertOrg(NETWORKADMIN, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + NodeInfoMap.UpsertNode(NETWORKADMIN, NODE1, NodeApproved) + AcctInfoMap.UpsertAccount(NETWORKADMIN, NETWORKADMIN, Acct1, true, AcctActive) + arbitraryPrivateKey, _ := crypto.GenerateKey() + hexNodeId := fmt.Sprintf("%x", crypto.FromECDSAPub(&arbitraryPrivateKey.PublicKey)[1:]) + + SetDefaultAccess() + + txnAllowed := ValidateNodeForTxn(hexNodeId, Acct1) + + testifyassert.False(t, txnAllowed) +} + +// test the cache limit +func TestLRUCacheLimit(t *testing.T) { + for i := 0; i < defaultOrgMapLimit ; i++ { + orgName := "ORG" + strconv.Itoa(i) + OrgInfoMap.UpsertOrg(orgName, "", NETWORKADMIN, big.NewInt(1), OrgApproved) + } + + o := OrgInfoMap.GetOrg("ORG1") + testifyassert.True(t, o != nil) +} diff --git a/core/types/transaction.go b/core/types/transaction.go index ed03969732..34e0241952 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -24,6 +24,7 @@ import ( "sync/atomic" fmt "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -42,6 +43,8 @@ func deriveSigner(V *big.Int) Signer { // joel: this is one of the two places we used a wrong signer to print txes if V.Sign() != 0 && isProtectedV(V) { return NewEIP155Signer(deriveChainId(V)) + } else if isPrivate(V) { + return QuorumPrivateTxSigner{} } else { return HomesteadSigner{} } @@ -202,6 +205,14 @@ func (tx *Transaction) To() *common.Address { return &to } +func (tx *Transaction) From() common.Address { + signer := deriveSigner(tx.data.V) + if from, err := Sender(signer, tx); err == nil { + return from + } + return common.Address{} +} + // Hash hashes the RLP encoding of tx. // It uniquely identifies the transaction. func (tx *Transaction) Hash() common.Hash { @@ -404,7 +415,7 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa for from, accTxs := range txs { // Ensure the sender address is from the signer acc, err := Sender(signer, accTxs[0]) - if (err == nil) { + if err == nil { heads = append(heads, accTxs[0]) txs[acc] = accTxs[1:] } else { @@ -498,6 +509,14 @@ func (tx *Transaction) IsPrivate() bool { return tx.data.V.Uint64() == 37 || tx.data.V.Uint64() == 38 } +/* + * Indicates that a transaction is private, but doesn't necessarily set the correct v value, as it can be called on + * an unsigned transaction. + * pre homestead signer, all v values were v=27 or v=28, with EIP155Signer that change, + * but SetPrivate() is also used on unsigned transactions to temporarily set the v value to indicate + * the transaction is intended to be private, and so that the correct signer can be selected. The signer will correctly + * set the valid v value (37 or 38): This helps minimize changes vs upstream go-ethereum code. + */ func (tx *Transaction) SetPrivate() { if tx.IsPrivate() { return diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 737e7c3017..a467f32209 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -126,7 +126,7 @@ var big8 = big.NewInt(8) func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { if tx.IsPrivate() { - return HomesteadSigner{}.Sender(tx) + return QuorumPrivateTxSigner{}.Sender(tx) } if !tx.Protected() { return HomesteadSigner{}.Sender(tx) @@ -136,16 +136,12 @@ func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { } V := new(big.Int).Sub(tx.data.V, s.chainIdMul) V.Sub(V, big8) - return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true, tx.IsPrivate()) + return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true) } // SignatureValues returns signature values. This signature // needs to be in the [R || S || V] format where V is 0 or 1. func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - if tx.IsPrivate() { - return HomesteadSigner{}.SignatureValues(tx, sig) - } - R, S, V, err = HomesteadSigner{}.SignatureValues(tx, sig) if err != nil { return nil, nil, nil, err @@ -187,7 +183,7 @@ func (hs HomesteadSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v } func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { - return recoverPlain(hs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, true, tx.IsPrivate()) + return recoverPlain(hs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, true) } type FrontierSigner struct{} @@ -205,11 +201,7 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * } r = new(big.Int).SetBytes(sig[:32]) s = new(big.Int).SetBytes(sig[32:64]) - if tx.IsPrivate() { - v = new(big.Int).SetBytes([]byte{sig[64] + 37}) - } else { - v = new(big.Int).SetBytes([]byte{sig[64] + 27}) - } + v = new(big.Int).SetBytes([]byte{sig[64] + 27}) return r, s, v, nil } @@ -227,15 +219,16 @@ func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { } func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { - return recoverPlain(fs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, false, tx.IsPrivate()) + return recoverPlain(fs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, false) } -func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool, isPrivate bool) (common.Address, error) { +func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) { if Vb.BitLen() > 8 { return common.Address{}, ErrInvalidSig } var offset uint64 - if isPrivate { + // private transaction has a v value of 37 or 38 + if isPrivate(Vb) { offset = 37 } else { offset = 27 diff --git a/core/types/transaction_signing_private.go b/core/types/transaction_signing_private.go new file mode 100644 index 0000000000..fef99a4583 --- /dev/null +++ b/core/types/transaction_signing_private.go @@ -0,0 +1,61 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +// Signs with Homestead +// obtains sender from EIP55Signer +type QuorumPrivateTxSigner struct{ HomesteadSigner } + +func (s QuorumPrivateTxSigner) Sender(tx *Transaction) (common.Address, error) { + return HomesteadSigner{}.Sender(tx) +} + +// SignatureValues returns signature values. This signature +// needs to be in the [R || S || V] format where V is 0 or 1. +func (qs QuorumPrivateTxSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + r, s, v, err := HomesteadSigner{}.SignatureValues(tx, sig) + // update v for private transaction marker: needs to be 37 (0+37) or 38 (1+37) for a private transaction. + v = new(big.Int).SetBytes([]byte{sig[64] + 37}) + return r, s, v, nil +} + +// Hash returns the hash to be signed by the sender. +// It does not uniquely identify the transaction. +func (s QuorumPrivateTxSigner) Hash(tx *Transaction) common.Hash { + return s.HomesteadSigner.Hash(tx) +} + +func (s QuorumPrivateTxSigner) Equal(s2 Signer) bool { + _, ok := s2.(QuorumPrivateTxSigner) + return ok +} + +/* + * If v is `37` or `38` that marks the transaction as private in Quorum. + * Note: this means quorum chains cannot have a public ethereum chainId == 1, as the EIP155 v + * param is `37` and `38` for the public Ethereum chain. Having a private chain with a chainId ==1 + * is discouraged in the general Ethereum ecosystem. + */ +func isPrivate(v *big.Int) bool { + return v.Cmp(big.NewInt(37)) == 0 || v.Cmp(big.NewInt(38)) == 0 +} diff --git a/core/types/transaction_signing_quorum_private_test.go b/core/types/transaction_signing_quorum_private_test.go new file mode 100644 index 0000000000..13ff830206 --- /dev/null +++ b/core/types/transaction_signing_quorum_private_test.go @@ -0,0 +1,63 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/ecdsa" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + testifyassert "github.com/stretchr/testify/assert" +) + +func signTxWithSigner(signer Signer, key *ecdsa.PrivateKey) (*Transaction, common.Address, error) { + addr := crypto.PubkeyToAddress(key.PublicKey) + tx := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) + signedTx, err := SignTx(tx, signer, key) + return signedTx, addr, err +} + +// run all the tests in this file +// $> go test $(go list ./...) -run QuorumSignPrivate + +// test with QuorumPrivateSigner +/* +* $> go test -run TestQuorumSignPrivateQuorum + */ +func TestQuorumSignPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + keys := []*big.Int{k0v, k1v} + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + qpPrivateSigner := QuorumPrivateTxSigner{HomesteadSigner{}} + + signedTx, addr, err := signTxWithSigner(qpPrivateSigner, key) + assert.Nil(err, err) + assert.True(signedTx.IsPrivate(), + fmt.Sprintf("The signed transaction is not private, signedTx.data.V is [%v]", signedTx.data.V)) + from, err := Sender(qpPrivateSigner, signedTx) + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from == address, [%x] == [%x]", from, addr)) + } + +} + diff --git a/core/types/transaction_signing_quorum_test.go b/core/types/transaction_signing_quorum_test.go new file mode 100644 index 0000000000..277c638b5b --- /dev/null +++ b/core/types/transaction_signing_quorum_test.go @@ -0,0 +1,356 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "fmt" + testifyassert "github.com/stretchr/testify/assert" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// run all the tests in this file +// $> go test $(go list ./...) -run TestSignQuorum + +// private key material to test both 0 and 1 bit for the recoveryId (v). +// key with v sign == 28 (Homestead) +var k0v, _ = new(big.Int).SetString("25807260602402504536675820444142779248993100028628438487502323668296269534891", 10) + +// key with v sign == 27 (Homestead) +var k1v, _ = new(big.Int).SetString("10148397294747000913768625849546502595195728826990639993137198410557736548965", 10) + +// helper to deterministically create an ECDSA key from an int. +func createKey(c elliptic.Curve, k *big.Int) (*ecdsa.PrivateKey, error) { + sk := new(ecdsa.PrivateKey) + sk.PublicKey.Curve = c + sk.D = k + sk.PublicKey.X, sk.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) + return sk, nil +} + +func signTx(key *ecdsa.PrivateKey, signer Signer) (*Transaction, common.Address, error) { + addr := crypto.PubkeyToAddress(key.PublicKey) + tx := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) + signedTx, err := SignTx(tx, signer, key) + //fmt.Printf("\ntx.data.V signTx after sign [%v] \n", signedTx.data.V) + return signedTx, addr, err +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Test public transactions signed by homestead Signer. Homestead sets the v param on a signed transaction to + * either 27 or 28. The v parameter is used for recovering the sender of the signed transaction. + * + * 1. Homestead: should be 27, 28 + * $> go test -run TestSignQuorumHomesteadPublic + */ +func TestSignQuorumHomesteadPublic(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + homeSinger := HomesteadSigner{} + + // odd parity should be 27 for Homestead + signedTx, addr, _ := signTx(k1, homeSinger) + + assert.True(signedTx.data.V.Cmp(big.NewInt(27)) == 0, fmt.Sprintf("v wasn't 27 it was [%v]", signedTx.data.V)) + + // recover address from signed TX + from, _ := Sender(homeSinger, signedTx) + //fmt.Printf("from [%v] == addr [%v]\n\n", from, from == addr) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + + // even parity should be 28 for Homestead + signedTx, addr, _ = signTx(k0, homeSinger) + assert.True(signedTx.data.V.Cmp(big.NewInt(28)) == 0, fmt.Sprintf("v wasn't 28 it was [%v]\n", signedTx.data.V)) + + // recover address from signed TX + from, _ = Sender(homeSinger, signedTx) + //fmt.Printf("from [%v] == addr [%v]\n", from, from == addr) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Test the public transactions signed by the EIP155Signer. + * The EIP155Signer was introduced to protect against replay + * attacks https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md and stores + * the CHAINID in the signed transaction's `v` parameter as `v = chainId * 2 + 35`. + * + * The EthEIP155Signer change breaks private quorum transactions when the chainId == 1 (mainnet chainId), + * as the v parameter on a public transaction and on a private transaction will both be 37, 38. + * + * $> go test -run TestSignQuorumEIP155Public + */ +func TestSignQuorumEIP155Public(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + // chainId 1 even EIP155Signer should be 37 conflicts with private transaction + var chainId int64 + chainId = 2 // 7 2 10 + + v0 := chainId*2 + 35 // sig[64] + 35 .. where sig[64] == 0 + v1 := chainId*2 + 36 // sig[64] + 35 .. where sig[64] == 1 + + // Will calculate v to be `v = CHAINID * 2 + 35` + // To compute V: + // 2 * 2 + 35 == 39 + // 2 * 2 + 36 == 40 + // To retrieve Sender, pull out 27, 28 Eth Frontier / Homestead values. + // 39 - (2 * 2) - 8 == 27 + // 40 - (2 * 2) - 8 == 28 + EIPsigner := NewEIP155Signer(big.NewInt(chainId)) + + signedTx, addr, _ := signTx(k0, EIPsigner) + + //fmt.Printf("After signing V is [%v] \n", signedTx.data.V) + assert.True(signedTx.data.V.Cmp(big.NewInt(v0)) == 0, fmt.Sprintf("v wasn't [%v] it was [%v]\n", v0, signedTx.data.V)) + from, _ := Sender(EIPsigner, signedTx) + + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + + // chainId 1 even EIP155Signer should be 38 conflicts with private transaction + assert.False(signedTx.IsPrivate(), fmt.Sprintf("Public transaction is set to a private transation v == [%v]", signedTx.data.V)) + + signedTx, addr, _ = signTx(k1, EIPsigner) + + assert.True(signedTx.data.V.Cmp(big.NewInt(v1)) == 0, fmt.Sprintf("v wasn't [%v], it was [%v]\n", v1, signedTx.data.V)) + from, _ = Sender(EIPsigner, signedTx) + + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * When the signer is EIP155Signer, chainId == 1 cannot be used because the EIP155 computed `v` value conflicts + * with the private `v` value that quorum uses to indicate a private transaction: v == 37 and v == 38. + * + * $> go test -run TestSignQuorumEIP155FailPublicChain1 + */ +func TestSignQuorumEIP155FailPublicChain1(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + // chainId 1 even EIP155Signer should be 37.38 which conflicts with private transaction + var chainId int64 + chainId = 1 + + v0 := chainId*2 + 35 // sig[64] + 35 .. where sig[64] == 0 + v1 := chainId*2 + 36 // sig[64] + 35 .. where sig[64] == 1 + + // Will calculate v to be `v = CHAINID * 2 + 35` + // To compute V: + // 2 * 1 + 35 == 37 + // 2 * 1 + 36 == 38 + // To retrieve Sender, pull out 27, 28 Eth Frontier / Homestead values. + // 37 - (1 * 2) - 8 == 27 + // 38 - (1 * 2) - 8 == 28 + EIPsigner := NewEIP155Signer(big.NewInt(chainId)) + + signedTx, addr, _ := signTx(k0, EIPsigner) + + // the calculated v value should equal `chainId * 2 + 35 ` + assert.True(signedTx.data.V.Cmp(big.NewInt(v0)) == 0, fmt.Sprintf("v wasn't [%v] it was "+ + "[%v]\n", v0, signedTx.data.V)) + // the sender will not be equal as HomesteadSigner{}.Sender(tx) is used because IsPrivate() will be true + // although it is a public tx. + // This is test to catch when / if this behavior changes. + assert.True(signedTx.IsPrivate(), "A public transaction with EIP155 and chainID 1 is expected to be "+ + "considered private, as its v param conflict with a private transaction. signedTx.IsPrivate() == [%v]", signedTx.IsPrivate()) + from, _ := Sender(EIPsigner, signedTx) + + assert.False(from == addr, fmt.Sprintf("Expected the sender of a public TX from chainId 1, \n "+ + "should not be recoverable from [%x] addr [%v] ", from, addr)) + + signedTx, addr, _ = signTx(k1, EIPsigner) + + // the calculated v value should equal `chainId * 2 + 35` + assert.True(signedTx.data.V.Cmp(big.NewInt(v1)) == 0, + fmt.Sprintf("v wasn't [%v] it was [%v]", v1, signedTx.data.V)) + + // the sender will not be equal as HomesteadSigner{}.Sender(tx) is used because IsPrivate() will be true + // although it is a public tx. + // This is test to catch when / if this behavior changes. + // we are signing the data with EIPsigner and chainID 1, so this would be considered a private tx. + assert.True(signedTx.IsPrivate(), "A public transaction with EIP155 and chainID 1 is expected to "+ + "to be considered private, as its v param conflict with a private transaction. "+ + "signedTx.IsPrivate() == [%v]", signedTx.IsPrivate()) + from, _ = Sender(EIPsigner, signedTx) + + assert.False(from == addr, fmt.Sprintf("Expected the sender of a public TX from chainId 1, "+ + "should not be recoverable from [%x] addr [%v] ", from, addr)) + +} + +/** +* As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior +* +* Use Homestead to sign and EIPSigner to recover. +* +* SendTransaction creates a transaction for the given argument, signs it and submit it to the transaction pool. +* func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { +* Current implementation in `internal/ethapi/api.go` +* +* accounts/keystore/keystore.SignTx(): would hash and sign with homestead +* +* When a private tx (obtained from json params PrivateFor) is submitted `internal/ethapi/api.go`: +* +* 1. sign with HomesteadSigner, this will set the v parameter to +* 27 or 28. // there is no indication that this is a private tx yet. +* +* 2. when submitting a transaction `submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, isPrivate bool)` + check isPrivate param, and call `tx.SetPrivate()`, this will update the `v` signature param (recoveryID) +* from 27 -> 37, 28 -> 38. // this is now considered a private tx. +* +* $> go test -run TestSignQuorumHomesteadEIP155SigningPrivateQuorum +*/ +func TestSignQuorumHomesteadEIP155SigningPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + keys := []*big.Int{k0v, k1v} + + homeSinger := HomesteadSigner{} + recoverySigner := NewEIP155Signer(big.NewInt(18)) + + // check for both sig[64] == 0, and sig[64] == 1 + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, homeSinger) + + assert.Nil(err, err) + // set to privateTX after the initial signing, this explicitly sets the v param. + // Note: only works when the tx was signed with the homesteadSinger (v==27 | 28). + signedTx.SetPrivate() + + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be private [%v]", signedTx.IsPrivate())) + // Try to recover Sender + from, err := Sender(recoverySigner, signedTx) + + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + } + +} + +/* + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * Use Homestead to sign and Homestead to recover. + * + * Signing private transactions with HomesteadSigner, and recovering a private transaction with + * HomesteadSigner works, but the transaction has to be set to private `signedTx.SetPrivate()` after + * the signature and before recovering the address. + * + * $> go test -run TestSignQuorumHomesteadOnlyPrivateQuorum + */ +func TestSignQuorumHomesteadOnlyPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + // check even and odd parity + keys := []*big.Int{k0v, k1v} + + homeSinger := HomesteadSigner{} + recoverySigner := HomesteadSigner{} + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, homeSinger) + + assert.Nil(err, err) + + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + // set to privateTX after the initial signing. + signedTx.SetPrivate() + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be "+ + "private [%v]", signedTx.IsPrivate())) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // Try to recover Sender + from, err := Sender(recoverySigner, signedTx) + + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. "+ + " Got %x want %x", from, addr)) + } + +} + +/* + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Use EIP155 to sign and EIP155 to recover (This is not a valid combination and does **not** work). + * + * Signing private transactions with EIP155Signer, and recovering a private transaction with + * EIP155Signer does **not** work. + * note: deriveChainId only checks for 27, 28 when using EIP155 + * note: In the case where the v param is not 27 or 28 when setting private it will always be set to 37 + * + * $> go test -run TestSignQuorumEIP155OnlyPrivateQuorum + */ +func TestSignQuorumEIP155OnlyPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + // check even and odd parity + keys := []*big.Int{k0v, k1v} + + EIP155Signer := NewEIP155Signer(big.NewInt(0)) + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, EIP155Signer) + + assert.Nil(err, err) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // set to privateTX after the initial signing. + signedTx.SetPrivate() + + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be private [%v]", signedTx.IsPrivate())) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // Try to recover Sender + from, err := Sender(EIP155Signer, signedTx) + + assert.Nil(err, err) + assert.False(from == addr, fmt.Sprintf("Expected recovery to fail. from [%x] should not equal "+ + "addr [%x]", from, addr)) + + } + +} diff --git a/core/vm/errors.go b/core/vm/errors.go index 66f9c5e462..771fde0224 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -26,6 +26,6 @@ var ( ErrInsufficientBalance = errors.New("insufficient balance for transfer") ErrContractAddressCollision = errors.New("contract address collision") - ErrReadOnlyValueTransfer = errors.New("VM in read-only mode. Value transfer prohibited.") - ErrNoCompatibleInterpreter = errors.New("no compatible interpreter") + ErrReadOnlyValueTransfer = errors.New("VM in read-only mode. Value transfer prohibited.") + ErrNoCompatibleInterpreter = errors.New("no compatible interpreter") ) diff --git a/core/vm/evm.go b/core/vm/evm.go index aaebfb5ce9..0135ace7b6 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 3440de3c4a..24f5c41bfb 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 5494585819..4349ffd295 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/crypto/bn256/cloudflare/main_test.go b/crypto/bn256/cloudflare/main_test.go index 0230f1b199..c0c85457be 100644 --- a/crypto/bn256/cloudflare/main_test.go +++ b/crypto/bn256/cloudflare/main_test.go @@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) { t.Error(err) continue } - t.Logf("%d: %x\n", n, g2.Marshal()) + t.Logf("%v: %x\n", n, g2.Marshal()) } } diff --git a/crypto/bn256/google/main_test.go b/crypto/bn256/google/main_test.go index 0230f1b199..c0c85457be 100644 --- a/crypto/bn256/google/main_test.go +++ b/crypto/bn256/google/main_test.go @@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) { t.Error(err) continue } - t.Logf("%d: %x\n", n, g2.Marshal()) + t.Logf("%v: %x\n", n, g2.Marshal()) } } diff --git a/dashboard/assets/package.json b/dashboard/assets/package.json index fb1a68e5b5..d5279a73d4 100644 --- a/dashboard/assets/package.json +++ b/dashboard/assets/package.json @@ -1,43 +1,43 @@ { "dependencies": { - "babel-core": "^6.26.0", - "babel-eslint": "^8.2.1", - "babel-loader": "^7.1.2", + "babel-core": "^6.26.3", + "babel-eslint": "^8.2.6", + "babel-loader": "^7.1.5", "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-plugin-transform-decorators-legacy": "^1.3.5", "babel-plugin-transform-flow-strip-types": "^6.22.0", "babel-plugin-transform-runtime": "^6.23.0", - "babel-preset-env": "^1.6.1", + "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "babel-runtime": "^6.26.0", - "classnames": "^2.2.5", - "css-loader": "^0.28.9", + "classnames": "^2.2.6", + "css-loader": "^2.1.1", "escape-html": "^1.0.3", - "eslint": "^4.16.0", + "eslint": "^4.19.1", "eslint-config-airbnb": "^16.1.0", - "eslint-loader": "^2.0.0", - "eslint-plugin-flowtype": "^2.41.0", - "eslint-plugin-import": "^2.8.0", - "eslint-plugin-jsx-a11y": "^6.0.3", - "eslint-plugin-react": "^7.5.1", - "file-loader": "^1.1.6", + "eslint-loader": "^2.1.2", + "eslint-plugin-flowtype": "^2.50.3", + "eslint-plugin-import": "^2.17.3", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-react": "^7.13.0", + "file-loader": "^1.1.11", "flow-bin": "^0.63.1", - "flow-bin-loader": "^1.0.2", - "flow-typed": "^2.2.3", - "material-ui": "^1.0.0-beta.30", - "material-ui-icons": "^1.0.0-beta.17", + "flow-bin-loader": "^1.0.3", + "flow-typed": "^2.5.2", + "material-ui": "^1.0.0-beta.47", + "material-ui-icons": "^1.0.0-beta.36", "path": "^0.12.7", - "react": "^16.2.0", - "react-dom": "^16.2.0", + "react": "^16.8.6", + "react-dom": "^16.8.6", "react-fa": "^5.0.0", - "react-transition-group": "^2.2.1", - "recharts": "^1.0.0-beta.9", + "react-transition-group": "^2.9.0", + "recharts": "^1.6.2", "style-loader": "^0.19.1", "url": "^0.11.0", "url-loader": "^0.6.2", - "webpack": "^3.10.0", - "webpack-dev-server": "^2.11.1" + "webpack": "^3.12.0", + "webpack-dev-server": "^2.11.5" }, "scripts": { "build": "NODE_ENV=production webpack", diff --git a/dashboard/assets/yarn.lock b/dashboard/assets/yarn.lock index 10277c9882..eff801de21 100644 --- a/dashboard/assets/yarn.lock +++ b/dashboard/assets/yarn.lock @@ -5,12 +5,14 @@ "@babel/code-frame@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" + integrity sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g== dependencies: "@babel/highlight" "7.0.0-beta.44" "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" + integrity sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ== dependencies: "@babel/types" "7.0.0-beta.44" jsesc "^2.5.1" @@ -21,6 +23,7 @@ "@babel/helper-function-name@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" + integrity sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg== dependencies: "@babel/helper-get-function-arity" "7.0.0-beta.44" "@babel/template" "7.0.0-beta.44" @@ -29,26 +32,53 @@ "@babel/helper-get-function-arity@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" + integrity sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw== dependencies: "@babel/types" "7.0.0-beta.44" "@babel/helper-split-export-declaration@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" + integrity sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA== dependencies: "@babel/types" "7.0.0-beta.44" "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" + integrity sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ== dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" +"@babel/polyfill@^7.0.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893" + integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.2" + +"@babel/runtime@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f" + integrity sha512-iOGRzUoONLOtmCvjUsZv3mZzgCT6ljHQY5fr1qG1QIiJQwtM7zbPWGGpa3QWETq+UqwWyJnoi5XZDZRwZDFciQ== + dependencies: + core-js "^2.5.3" + regenerator-runtime "^0.11.1" + +"@babel/runtime@^7.0.0-beta.42", "@babel/runtime@^7.1.2": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" + integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" + integrity sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng== dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/types" "7.0.0-beta.44" @@ -58,6 +88,7 @@ "@babel/traverse@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" + integrity sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA== dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/generator" "7.0.0-beta.44" @@ -73,135 +104,194 @@ "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" + integrity sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ== dependencies: esutils "^2.0.2" lodash "^4.2.0" to-fast-properties "^2.0.0" +"@octokit/rest@^15.12.1": + version "15.18.1" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.18.1.tgz#ec7fb0f8775ef64dc095fae6635411d3fbff9b62" + integrity sha512-g2tecjp2TEtYV8bKAFvfQtu+W29HM7ektmWmw8zrMy9/XCKDEYRErR2YvvhN9+IxkLC4O3lDqYP4b6WgsL6Utw== + dependencies: + before-after-hook "^1.1.0" + btoa-lite "^1.0.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lodash "^4.17.4" + node-fetch "^2.1.1" + universal-user-agent "^2.0.0" + url-template "^2.0.8" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + "@types/jss@^9.3.0": - version "9.5.0" - resolved "https://registry.yarnpkg.com/@types/jss/-/jss-9.5.0.tgz#65d9b5c61f1e95ad3acd53e9a8b2d2342aa917e8" + version "9.5.8" + resolved "https://registry.yarnpkg.com/@types/jss/-/jss-9.5.8.tgz#258391f42211c042fc965508d505cbdc579baa5b" + integrity sha512-bBbHvjhm42UKki+wZpR89j73ykSXg99/bhuKuYYePtpma3ZAnmeGnl0WxXiZhPGsIfzKwCUkpPC0jlrVMBfRxA== dependencies: - csstype "^1.6.0" + csstype "^2.0.0" + indefinite-observable "^1.0.1" -"@types/react-transition-group@^2.0.6": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.7.tgz#2847292d54c5685d982ae5a3ecb6960946689d87" +"@types/prop-types@*": + version "15.7.1" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6" + integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg== + +"@types/react-transition-group@^2.0.8": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.9.2.tgz#c48cf2a11977c8b4ff539a1c91d259eaa627028d" + integrity sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA== dependencies: "@types/react" "*" "@types/react@*": - version "16.0.40" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.40.tgz#caabc2296886f40b67f6fc80f0f3464476461df9" + version "16.8.20" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.20.tgz#4f633ecbd0a4d56d0ccc50fff6f9321bbcd7d583" + integrity sha512-ZLmI+ubSJpfUIlQuULDDrdyuFQORBuGOvNnMue8HeA0GVrAJbWtZQhcBvnBPNRBI/GrfSfrKPFhthzC2SLEtLQ== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== dependencies: - mime-types "~2.1.18" - negotiator "0.6.1" + mime-types "~2.1.24" + negotiator "0.6.2" acorn-dynamic-import@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + integrity sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ= dependencies: acorn "^4.0.3" acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= dependencies: acorn "^3.0.4" acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= -acorn@^5.0.0, acorn@^5.4.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.0.tgz#1abb587fbf051f94e3de20e6b26ef910b1828298" +acorn@^5.0.0, acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +agent-base@4, agent-base@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= -ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" - -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" +ajv-keywords@^3.1.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" + integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== ajv@^5.0.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^6.0.1, ajv@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.0.tgz#afac295bbaa0152449e522742e4547c1ae9328d2" +ajv@^6.1.0, ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== dependencies: - fast-deep-equal "^1.0.0" + fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= dependencies: kind-of "^3.0.2" longest "^1.0.1" repeat-string "^1.5.2" -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - ansi-escapes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" normalize-path "^2.1.1" @@ -209,10 +299,12 @@ anymatch@^2.0.0: aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -220,49 +312,52 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" -aria-query@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.7.1.tgz#26cbb5aff64144b0a825be1846e0b16cfa00b11e" +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= dependencies: ast-types-flow "0.0.7" commander "^2.11.0" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -arr-flatten@^1.0.1, arr-flatten@^1.1.0: +arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-flatten@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== array-includes@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= dependencies: define-properties "^1.1.2" es-abstract "^1.7.0" @@ -270,121 +365,99 @@ array-includes@^3.0.3: array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: + object-assign "^4.1.1" util "0.10.3" assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types-flow@0.0.7: +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= async@^2.1.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" - dependencies: - lodash "^4.14.0" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -atob@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d" - -autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + lodash "^4.17.11" -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -axobject-query@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0" +axobject-query@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" + integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== dependencies: ast-types-flow "0.0.7" babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= dependencies: chalk "^1.1.3" esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^6.26.0: +babel-core@^6.26.0, babel-core@^6.26.3: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== dependencies: babel-code-frame "^6.26.0" babel-generator "^6.26.0" @@ -406,20 +479,22 @@ babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.7" -babel-eslint@^8.2.1: - version "8.2.3" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.3.tgz#1a2e6681cc9bc4473c32899e59915e19cd6733cf" +babel-eslint@^8.2.6: + version "8.2.6" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" + integrity sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA== dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/traverse" "7.0.0-beta.44" "@babel/types" "7.0.0-beta.44" babylon "7.0.0-beta.44" - eslint-scope "~3.7.1" + eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== dependencies: babel-messages "^6.23.0" babel-runtime "^6.26.0" @@ -433,6 +508,7 @@ babel-generator@^6.26.0: babel-helper-bindify-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + integrity sha1-FMGeXxQte0fxmlJDHlKxzLxAozA= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -441,6 +517,7 @@ babel-helper-bindify-decorators@^6.24.1: babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= dependencies: babel-helper-explode-assignable-expression "^6.24.1" babel-runtime "^6.22.0" @@ -449,6 +526,7 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-builder-react-jsx@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" @@ -457,6 +535,7 @@ babel-helper-builder-react-jsx@^6.24.1: babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -466,6 +545,7 @@ babel-helper-call-delegate@^6.24.1: babel-helper-define-map@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.26.0" @@ -475,6 +555,7 @@ babel-helper-define-map@^6.24.1: babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -483,6 +564,7 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-helper-explode-class@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= dependencies: babel-helper-bindify-decorators "^6.24.1" babel-runtime "^6.22.0" @@ -492,6 +574,7 @@ babel-helper-explode-class@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" @@ -502,6 +585,7 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -509,6 +593,7 @@ babel-helper-get-function-arity@^6.24.1: babel-helper-hoist-variables@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -516,6 +601,7 @@ babel-helper-hoist-variables@^6.24.1: babel-helper-optimise-call-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -523,6 +609,7 @@ babel-helper-optimise-call-expression@^6.24.1: babel-helper-regex@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" @@ -531,6 +618,7 @@ babel-helper-regex@^6.24.1: babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -541,6 +629,7 @@ babel-helper-remap-async-to-generator@^6.24.1: babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: babel-helper-optimise-call-expression "^6.24.1" babel-messages "^6.23.0" @@ -552,13 +641,15 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-loader@^7.1.2: - version "7.1.4" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.4.tgz#e3463938bd4e6d55d1c174c5485d406a188ed015" +babel-loader@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.5.tgz#e3ee0cd7394aa557e013b02d3e492bfd07aa6d68" + integrity sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw== dependencies: find-cache-dir "^1.0.0" loader-utils "^1.0.2" @@ -567,74 +658,91 @@ babel-loader@^7.1.2: babel-messages@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= dependencies: babel-runtime "^6.22.0" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= babel-plugin-syntax-async-generators@^6.5.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= babel-plugin-syntax-class-constructor-call@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + integrity sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY= babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= babel-plugin-syntax-do-expressions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" + integrity sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0= babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= babel-plugin-syntax-export-extensions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + integrity sha1-cKFITw+QiaToStRLrDU8lbmxJyE= babel-plugin-syntax-flow@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= babel-plugin-syntax-function-bind@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" + integrity sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y= babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= babel-plugin-transform-async-generator-functions@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-generators "^6.5.0" @@ -643,6 +751,7 @@ babel-plugin-transform-async-generator-functions@^6.24.1: babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-functions "^6.8.0" @@ -651,6 +760,7 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-transform-class-constructor-call@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + integrity sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk= dependencies: babel-plugin-syntax-class-constructor-call "^6.18.0" babel-runtime "^6.22.0" @@ -659,15 +769,17 @@ babel-plugin-transform-class-constructor-call@^6.24.1: babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= dependencies: babel-helper-function-name "^6.24.1" babel-plugin-syntax-class-properties "^6.8.0" babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-decorators-legacy@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925" +babel-plugin-transform-decorators-legacy@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz#0e492dffa0edd70529072887f8aa86d4dd8b40a1" + integrity sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA== dependencies: babel-plugin-syntax-decorators "^6.1.18" babel-runtime "^6.2.0" @@ -676,6 +788,7 @@ babel-plugin-transform-decorators-legacy@^1.3.4: babel-plugin-transform-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + integrity sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0= dependencies: babel-helper-explode-class "^6.24.1" babel-plugin-syntax-decorators "^6.13.0" @@ -686,6 +799,7 @@ babel-plugin-transform-decorators@^6.24.1: babel-plugin-transform-do-expressions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz#28ccaf92812d949c2cd1281f690c8fdc468ae9bb" + integrity sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs= dependencies: babel-plugin-syntax-do-expressions "^6.8.0" babel-runtime "^6.22.0" @@ -693,18 +807,21 @@ babel-plugin-transform-do-expressions@^6.22.0: babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= dependencies: babel-runtime "^6.26.0" babel-template "^6.26.0" @@ -715,6 +832,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0: babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= dependencies: babel-helper-define-map "^6.24.1" babel-helper-function-name "^6.24.1" @@ -729,6 +847,7 @@ babel-plugin-transform-es2015-classes@^6.23.0: babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -736,12 +855,14 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0: babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -749,12 +870,14 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0: babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -763,20 +886,23 @@ babel-plugin-transform-es2015-function-name@^6.22.0: babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= dependencies: babel-plugin-transform-es2015-modules-commonjs "^6.24.1" babel-runtime "^6.22.0" babel-template "^6.24.1" babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== dependencies: babel-plugin-transform-strict-mode "^6.24.1" babel-runtime "^6.26.0" @@ -786,6 +912,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -794,6 +921,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0: babel-plugin-transform-es2015-modules-umd@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= dependencies: babel-plugin-transform-es2015-modules-amd "^6.24.1" babel-runtime "^6.22.0" @@ -802,6 +930,7 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0: babel-plugin-transform-es2015-object-super@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" @@ -809,6 +938,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0: babel-plugin-transform-es2015-parameters@^6.23.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= dependencies: babel-helper-call-delegate "^6.24.1" babel-helper-get-function-arity "^6.24.1" @@ -820,6 +950,7 @@ babel-plugin-transform-es2015-parameters@^6.23.0: babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -827,12 +958,14 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0: babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -841,18 +974,21 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0: babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -861,6 +997,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= dependencies: babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" babel-plugin-syntax-exponentiation-operator "^6.8.0" @@ -869,6 +1006,7 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e babel-plugin-transform-export-extensions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" + integrity sha1-U3OLR+deghhYnuqUbLvTkQm75lM= dependencies: babel-plugin-syntax-export-extensions "^6.8.0" babel-runtime "^6.22.0" @@ -876,6 +1014,7 @@ babel-plugin-transform-export-extensions@^6.22.0: babel-plugin-transform-flow-strip-types@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + integrity sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988= dependencies: babel-plugin-syntax-flow "^6.18.0" babel-runtime "^6.22.0" @@ -883,6 +1022,7 @@ babel-plugin-transform-flow-strip-types@^6.22.0: babel-plugin-transform-function-bind@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz#c6fb8e96ac296a310b8cf8ea401462407ddf6a97" + integrity sha1-xvuOlqwpajELjPjqQBRiQH3fapc= dependencies: babel-plugin-syntax-function-bind "^6.8.0" babel-runtime "^6.22.0" @@ -890,6 +1030,7 @@ babel-plugin-transform-function-bind@^6.22.0: babel-plugin-transform-object-rest-spread@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= dependencies: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.26.0" @@ -897,12 +1038,14 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-transform-react-display-name@^6.23.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + integrity sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-react-jsx-self@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + integrity sha1-322AqdomEqEh5t3XVYvL7PBuY24= dependencies: babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" @@ -910,6 +1053,7 @@ babel-plugin-transform-react-jsx-self@^6.22.0: babel-plugin-transform-react-jsx-source@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + integrity sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY= dependencies: babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" @@ -917,6 +1061,7 @@ babel-plugin-transform-react-jsx-source@^6.22.0: babel-plugin-transform-react-jsx@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + integrity sha1-hAoCjn30YN/DotKfDA2R9jduZqM= dependencies: babel-helper-builder-react-jsx "^6.24.1" babel-plugin-syntax-jsx "^6.8.0" @@ -925,33 +1070,29 @@ babel-plugin-transform-react-jsx@^6.24.1: babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= dependencies: regenerator-transform "^0.10.0" babel-plugin-transform-runtime@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" + integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - -babel-preset-env@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-syntax-trailing-function-commas "^6.22.0" @@ -980,19 +1121,21 @@ babel-preset-env@^1.6.1: babel-plugin-transform-es2015-unicode-regex "^6.22.0" babel-plugin-transform-exponentiation-operator "^6.22.0" babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" + browserslist "^3.2.6" invariant "^2.2.2" semver "^5.3.0" babel-preset-flow@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + integrity sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0= dependencies: babel-plugin-transform-flow-strip-types "^6.22.0" babel-preset-react@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + integrity sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A= dependencies: babel-plugin-syntax-jsx "^6.3.13" babel-plugin-transform-react-display-name "^6.23.0" @@ -1004,6 +1147,7 @@ babel-preset-react@^6.24.1: babel-preset-stage-0@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz#5642d15042f91384d7e5af8bc88b1db95b039e6a" + integrity sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo= dependencies: babel-plugin-transform-do-expressions "^6.22.0" babel-plugin-transform-function-bind "^6.22.0" @@ -1012,6 +1156,7 @@ babel-preset-stage-0@^6.24.1: babel-preset-stage-1@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" + integrity sha1-dpLNfc1oSZB+auSgqFWJz7niv7A= dependencies: babel-plugin-transform-class-constructor-call "^6.24.1" babel-plugin-transform-export-extensions "^6.22.0" @@ -1020,6 +1165,7 @@ babel-preset-stage-1@^6.24.1: babel-preset-stage-2@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + integrity sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE= dependencies: babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" @@ -1029,6 +1175,7 @@ babel-preset-stage-2@^6.24.1: babel-preset-stage-3@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= dependencies: babel-plugin-syntax-trailing-function-commas "^6.22.0" babel-plugin-transform-async-generator-functions "^6.24.1" @@ -1039,6 +1186,7 @@ babel-preset-stage-3@^6.24.1: babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= dependencies: babel-core "^6.26.0" babel-runtime "^6.26.0" @@ -1051,6 +1199,7 @@ babel-register@^6.26.0: babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" @@ -1058,6 +1207,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtim babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= dependencies: babel-runtime "^6.26.0" babel-traverse "^6.26.0" @@ -1068,6 +1218,7 @@ babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= dependencies: babel-code-frame "^6.26.0" babel-messages "^6.23.0" @@ -1082,6 +1233,7 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= dependencies: babel-runtime "^6.26.0" esutils "^2.0.2" @@ -1091,26 +1243,32 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: babylon@7.0.0-beta.44: version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" + integrity sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g== babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801" + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -1123,56 +1281,66 @@ base@^0.11.1: batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" +before-after-hook@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d" + integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg== -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" +big-integer@^1.6.17: + version "1.6.44" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" + integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== -"binary@>= 0.3.0 < 1": +binary@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= dependencies: buffers "~0.1.1" chainsaw "~0.1.0" -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" +bluebird@~3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== -body-parser@1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== dependencies: - bytes "3.0.0" + bytes "3.1.0" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.1" - http-errors "~1.6.2" - iconv-lite "0.4.19" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" on-finished "~2.3.0" - qs "6.5.1" - raw-body "2.3.2" - type-is "~1.6.15" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" bonjour@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= dependencies: array-flatten "^2.1.0" deep-equal "^1.0.1" @@ -1181,38 +1349,24 @@ bonjour@^3.5.0: multicast-dns "^6.0.1" multicast-dns-service-types "^1.1.0" -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^2.3.0, braces@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" - define-property "^1.0.0" extend-shallow "^2.0.1" fill-range "^4.0.0" isobject "^3.0.1" - kind-of "^6.0.2" repeat-element "^1.1.2" snapdragon "^0.8.1" snapdragon-node "^2.0.1" @@ -1222,14 +1376,17 @@ braces@^2.3.0, braces@^2.3.1: brcast@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/brcast/-/brcast-3.0.1.tgz#6256a8349b20de9eed44257a9b24d71493cd48dd" + integrity sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg== brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" cipher-base "^1.0.0" @@ -1239,24 +1396,28 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: safe-buffer "^5.0.1" browserify-cipher@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" browserify-des "^1.0.0" evp_bytestokey "^1.0.0" browserify-des@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" des.js "^1.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" browserify-rsa@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= dependencies: bn.js "^4.1.0" randombytes "^2.0.1" @@ -1264,6 +1425,7 @@ browserify-rsa@^4.0.0: browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= dependencies: bn.js "^4.1.1" browserify-rsa "^4.0.0" @@ -1276,34 +1438,47 @@ browserify-sign@^4.0.0: browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" -browserslist@^2.1.2: - version "2.11.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" - dependencies: - caniuse-lite "^1.0.30000792" - electron-to-chromium "^1.3.30" +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof-polyfill@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf" + integrity sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8= buffer-indexof@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.3.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1312,22 +1487,27 @@ buffer@^4.3.0: buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - -builtin-modules@^1.0.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1339,19 +1519,35 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= dependencies: callsites "^0.2.0" callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= dependencies: camelcase "^2.0.0" map-obj "^1.0.0" @@ -1359,60 +1555,52 @@ camelcase-keys@^2.0.0: camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" - dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000811" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000811.tgz#19efb9238393d40078332c34485c818d641c4305" - -caniuse-lite@^1.0.30000792: - version "1.0.30000811" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000811.tgz#0b6e40f2efccc27bd3cb52f91ee7ca4673d77d10" +camelcase@^5.0.0, camelcase@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +caniuse-lite@^1.0.30000844: + version "1.0.30000974" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz#b7afe14ee004e97ce6dc73e3f878290a12928ad8" + integrity sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww== center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= dependencies: align-text "^0.1.3" lazy-cache "^1.0.3" -chain-function@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc" - chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= dependencies: traverse ">=0.3.0 <0.4" chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1420,17 +1608,10 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.1.0, chalk@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1439,36 +1620,46 @@ chalk@^2.1.0, chalk@^2.3.1: change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" + integrity sha1-6LL+PX8at9aaMhma/5HqaTFAlRU= chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= -chokidar@^2.0.0, chokidar@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" +chokidar@^2.0.2, chokidar@^2.1.2: + version "2.1.6" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" + integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.0.0" + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -1476,39 +1667,39 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - dependencies: - chalk "^1.1.3" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" isobject "^3.0.0" static-extend "^0.1.1" -classnames@2.2.5, classnames@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" +classnames@^2.2.5, classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= dependencies: center-align "^0.1.1" right-align "^0.1.1" @@ -1517,201 +1708,212 @@ cliui@^2.1.0: cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -clone@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - dependencies: - q "^1.1.2" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.3.0, color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: - color-name "^1.1.1" + color-name "1.1.3" -color-name@^1.0.0, color-name@^1.1.1: +color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - dependencies: - color-name "^1.0.0" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" - -colors@^1.1.2, colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" - dependencies: - delayed-stream "~1.0.0" +colors@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== commander@^2.11.0: - version "2.14.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compressible@~2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9" +compressible@~2.0.16: + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== dependencies: - mime-db ">= 1.33.0 < 2" + mime-db ">= 1.40.0 < 2" -compression@^1.5.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.2.tgz#aaffbcd6aaf854b44ebb280353d5ad1651f59a69" +compression@^1.7.3: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== dependencies: - accepts "~1.3.4" + accepts "~1.3.5" bytes "3.0.0" - compressible "~2.0.13" + compressible "~2.0.16" debug "2.6.9" - on-headers "~1.0.1" - safe-buffer "5.1.1" + on-headers "~1.0.2" + safe-buffer "5.1.2" vary "~1.1.2" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= concat-stream@^1.6.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.1.tgz#261b8f518301f1d834e36342b9fea095d2620a26" + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== dependencies: + buffer-from "^1.0.0" inherits "^2.0.3" readable-stream "^2.2.2" typedarray "^0.0.6" connect-history-api-fallback@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= dependencies: date-now "^0.1.4" console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-js@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.1, core-js@^2.5.3, core-js@^2.6.5: + version "2.6.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" + integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= create-ecdh@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== dependencies: bn.js "^4.1.0" elliptic "^6.0.0" create-hash@^1.1.0, create-hash@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" inherits "^2.0.1" - ripemd160 "^2.0.0" + md5.js "^1.3.4" + ripemd160 "^2.0.1" sha.js "^2.4.0" create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.6" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" create-hash "^1.1.0" @@ -1723,24 +1925,32 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" browserify-sign "^4.0.0" @@ -1754,262 +1964,231 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - -css-loader@^0.28.9: - version "0.28.10" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.10.tgz#40282e79230f7bcb4e483efa631d670b735ebf42" - dependencies: - babel-code-frame "^6.26.0" - css-selector-tokenizer "^0.7.0" - cssnano "^3.10.0" - icss-utils "^2.1.0" - loader-utils "^1.0.2" - lodash.camelcase "^4.3.0" - object-assign "^4.1.1" - postcss "^5.0.6" - postcss-modules-extract-imports "^1.2.0" - postcss-modules-local-by-default "^1.2.0" - postcss-modules-scope "^1.1.0" - postcss-modules-values "^1.3.0" +css-loader@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" + integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== + dependencies: + camelcase "^5.2.0" + icss-utils "^4.1.0" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.14" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^2.0.6" + postcss-modules-scope "^2.1.0" + postcss-modules-values "^2.0.0" postcss-value-parser "^3.3.0" - source-list-map "^2.0.0" - -css-selector-tokenizer@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" - dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" + schema-utils "^1.0.0" css-vendor@^0.3.8: version "0.3.8" resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-0.3.8.tgz#6421cfd3034ce664fe7673972fd0119fc28941fa" + integrity sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo= dependencies: is-in-browser "^1.0.2" -cssesc@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" - -cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" - dependencies: - clap "^1.0.9" - source-map "^0.5.3" +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^1.6.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-1.8.2.tgz#2c0f16da08b99f13fe7fbb242e87d1a19dbe77a7" +csstype@^2.0.0, csstype@^2.2.0: + version "2.6.5" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.5.tgz#1cd1dff742ebf4d7c991470ae71e12bb6751e034" + integrity sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA== currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= dependencies: array-find-index "^1.0.1" d3-array@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc" + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== d3-collection@1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2" + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== d3-color@1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b" + version "1.2.3" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.3.tgz#6c67bb2af6df3cc8d79efcc4d3a3e83e28c8048f" + integrity sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw== d3-format@1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a" + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.2.tgz#6a96b5e31bcb98122a30863f7d92365c00603562" + integrity sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ== -d3-interpolate@1, d3-interpolate@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6" +d3-interpolate@1, d3-interpolate@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68" + integrity sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w== dependencies: d3-color "1" d3-path@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764" + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.7.tgz#8de7cd693a75ac0b5480d3abaccd94793e58aae8" + integrity sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA== -d3-scale@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.6.tgz#bce19da80d3a0cf422c9543ae3322086220b34ed" +d3-scale@^2.1.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" + integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== dependencies: d3-array "^1.2.0" d3-collection "1" - d3-color "1" d3-format "1" d3-interpolate "1" d3-time "1" d3-time-format "2" -d3-shape@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777" +d3-shape@^1.2.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.5.tgz#e81aea5940f59f0a79cfccac012232a8987c6033" + integrity sha512-VKazVR3phgD+MUCldapHD7P9kcrvPcexeX/PkMJmkUov4JM8IxsSg1DvbYoYich9AtdTsa5nNk2++ImPiDiSxg== dependencies: d3-path "1" d3-time-format@2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.1.tgz#85b7cdfbc9ffca187f14d3c456ffda268081bb31" + version "2.1.3" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.3.tgz#ae06f8e0126a9d60d6364eac5b1533ae1bac826b" + integrity sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA== dependencies: d3-time "1" d3-time@1: - version "1.0.8" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.8.tgz#dbd2d6007bf416fe67a76d17947b784bffea1e84" + version "1.0.11" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.11.tgz#1d831a3e25cd189eb256c17770a666368762bbce" + integrity sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw== d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== dependencies: - es5-ext "^0.10.9" + es5-ext "^0.10.50" + type "^1.0.1" -damerau-levenshtein@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" +damerau-levenshtein@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414" + integrity sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA== date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^3.1.0: +debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +debug@^3.1.0, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decimal.js-light@^2.4.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.0.tgz#ca7faf504c799326df94b0ab920424fdfc125348" + integrity sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg== decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-response@^3.2.0: +decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= deepmerge@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.0.1.tgz#25c1c24f110fb914f80001b925264dd77f3f4312" + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" + object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - del@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= dependencies: globby "^6.1.0" is-path-cwd "^1.0.0" @@ -2018,25 +2197,20 @@ del@^3.0.0: pify "^3.0.0" rimraf "^2.2.8" -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" - -depd@~1.1.1: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -2044,24 +2218,29 @@ des.js@^1.0.0: destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= dependencies: repeating "^2.0.0" detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= -detect-node@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== diffie-hellman@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" miller-rabin "^4.0.0" @@ -2070,10 +2249,12 @@ diffie-hellman@^5.0.0: dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= dns-packet@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== dependencies: ip "^1.1.0" safe-buffer "^5.0.1" @@ -2081,55 +2262,68 @@ dns-packet@^1.3.1: dns-txt@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= dependencies: buffer-indexof "^1.0.0" doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.2, doctrine@^2.1.0: +doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" -dom-helpers@^3.2.0, dom-helpers@^3.2.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6" +dom-helpers@^3.2.1, dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + dependencies: + readable-stream "^2.0.2" duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: - version "1.3.34" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed" +electron-to-chromium@^1.3.47: + version "1.3.164" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.164.tgz#8680b875577882c1572c42218d53fa9ba5f71d5d" + integrity sha512-VLlalqUeduN4+fayVtRZvGP2Hl1WrRxlwzh2XVVMJym3IFrQUS29BFQ1GP/BxOJXJI1OFCrJ5BnFEsAe8NHtOg== elliptic@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2139,27 +2333,39 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" -emoji-regex@^6.1.0: - version "6.5.1" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" +emoji-regex@^7.0.1, emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= -encodeurl@~1.0.1: +encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24= dependencies: graceful-fs "^4.1.2" memory-fs "^0.4.0" @@ -2169,43 +2375,51 @@ enhanced-resolve@^3.4.0: errno@^0.1.3: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== dependencies: prr "~1.0.1" error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.7.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" +es-abstract@^1.11.0, es-abstract@^1.7.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== dependencies: - es-to-primitive "^1.1.1" + es-to-primitive "^1.2.0" function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" + has "^1.0.3" + is-callable "^1.1.4" is-regex "^1.0.4" + object-keys "^1.0.12" -es-to-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: - is-callable "^1.1.1" + is-callable "^1.1.4" is-date-object "^1.0.1" - is-symbol "^1.0.1" + is-symbol "^1.0.2" -es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.39" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.39.tgz#fca21b67559277ca4ac1a1ed7048b107b6f76d87" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.50" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" + integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== dependencies: es6-iterator "~2.0.3" es6-symbol "~3.1.1" + next-tick "^1.0.0" -es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= dependencies: d "1" es5-ext "^0.10.35" @@ -2214,6 +2428,7 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: es6-map@^0.1.3: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= dependencies: d "1" es5-ext "~0.10.14" @@ -2222,9 +2437,22 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= dependencies: d "1" es5-ext "~0.10.14" @@ -2235,30 +2463,35 @@ es6-set@~0.1.5: es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= dependencies: d "1" es5-ext "~0.10.14" es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== dependencies: d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" es6-symbol "^3.1.1" escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= dependencies: es6-map "^0.1.3" es6-weak-map "^2.0.1" @@ -2268,25 +2501,29 @@ escope@^3.6.0: eslint-config-airbnb-base@^12.1.0: version "12.1.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" + integrity sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA== dependencies: eslint-restricted-globals "^0.1.1" eslint-config-airbnb@^16.1.0: version "16.1.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz#2546bfb02cc9fe92284bf1723ccf2e87bc45ca46" + integrity sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw== dependencies: eslint-config-airbnb-base "^12.1.0" -eslint-import-resolver-node@^0.3.1: +eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== dependencies: debug "^2.6.9" resolve "^1.5.0" -eslint-loader@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.0.0.tgz#d136619b5c684e36531ffc28c60a56e404608f5d" +eslint-loader@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.2.tgz#453542a1230d6ffac90e4e7cb9cadba9d851be68" + integrity sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg== dependencies: loader-fs-cache "^1.0.0" loader-utils "^1.0.2" @@ -2294,62 +2531,82 @@ eslint-loader@^2.0.0: object-hash "^1.1.4" rimraf "^2.6.1" -eslint-module-utils@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" +eslint-module-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" + integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== dependencies: debug "^2.6.8" - pkg-dir "^1.0.0" + pkg-dir "^2.0.0" -eslint-plugin-flowtype@^2.41.0: - version "2.46.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.46.1.tgz#c4f81d580cd89c82bc3a85a1ccf4ae3a915143a4" +eslint-plugin-flowtype@^2.50.3: + version "2.50.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" + integrity sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ== dependencies: - lodash "^4.15.0" + lodash "^4.17.10" -eslint-plugin-import@^2.8.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz#26002efbfca5989b7288ac047508bd24f217b169" +eslint-plugin-import@^2.17.3: + version "2.17.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz#00548b4434c18faebaba04b24ae6198f280de189" + integrity sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q== dependencies: - builtin-modules "^1.1.1" + array-includes "^3.0.3" contains-path "^0.1.0" - debug "^2.6.8" + debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.1.1" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" read-pkg-up "^2.0.0" + resolve "^1.11.0" -eslint-plugin-jsx-a11y@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz#54583d1ae442483162e040e13cc31865465100e5" +eslint-plugin-jsx-a11y@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c" + integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w== dependencies: - aria-query "^0.7.0" + aria-query "^3.0.0" array-includes "^3.0.3" - ast-types-flow "0.0.7" - axobject-query "^0.1.0" - damerau-levenshtein "^1.0.0" - emoji-regex "^6.1.0" - jsx-ast-utils "^2.0.0" + ast-types-flow "^0.0.7" + axobject-query "^2.0.2" + damerau-levenshtein "^1.0.4" + emoji-regex "^7.0.2" + has "^1.0.3" + jsx-ast-utils "^2.0.1" -eslint-plugin-react@^7.5.1: - version "7.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz#f606c719dbd8a1a2b3d25c16299813878cca0160" +eslint-plugin-react@^7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz#bc13fd7101de67996ea51b33873cd9dc2b7e5758" + integrity sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ== dependencies: - doctrine "^2.0.2" - has "^1.0.1" - jsx-ast-utils "^2.0.1" - prop-types "^15.6.0" + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.1.0" + object.fromentries "^2.0.0" + prop-types "^15.7.2" + resolve "^1.10.1" eslint-restricted-globals@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= -eslint-scope@^3.7.1, eslint-scope@~3.7.1: +eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2357,10 +2614,12 @@ eslint-scope@^3.7.1, eslint-scope@~3.7.1: eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^4.16.0: - version "4.18.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.2.tgz#0f81267ad1012e7d2051e186a9004cc2267b8d45" +eslint@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -2371,7 +2630,7 @@ eslint@^4.16.0: doctrine "^2.1.0" eslint-scope "^3.7.1" eslint-visitor-keys "^1.0.0" - espree "^3.5.2" + espree "^3.5.4" esquery "^1.0.0" esutils "^2.0.2" file-entry-cache "^2.0.0" @@ -2393,6 +2652,7 @@ eslint@^4.16.0: path-is-inside "^1.0.2" pluralize "^7.0.0" progress "^2.0.0" + regexpp "^1.0.1" require-uncached "^1.0.3" semver "^5.3.0" strip-ansi "^4.0.0" @@ -2400,69 +2660,77 @@ eslint@^4.16.0: table "4.0.2" text-table "~0.2.0" -espree@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6" +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== dependencies: - acorn "^5.4.0" + acorn "^5.5.0" acorn-jsx "^3.0.0" -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== dependencies: estraverse "^4.0.0" esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== dependencies: estraverse "^4.1.0" estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= dependencies: d "1" es5-ext "~0.10.14" -eventemitter3@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" +eventemitter3@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -events@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== eventsource@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + integrity sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI= dependencies: original ">=0.0.5" evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" safe-buffer "^5.1.1" @@ -2470,6 +2738,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2479,15 +2748,23 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: - is-posix-bracket "^0.1.0" + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -2497,81 +2774,70 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - express@^4.16.2: - version "4.16.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== dependencies: - accepts "~1.3.4" + accepts "~1.3.7" array-flatten "1.1.1" - body-parser "1.18.2" - content-disposition "0.5.2" + body-parser "1.19.0" + content-disposition "0.5.3" content-type "~1.0.4" - cookie "0.3.1" + cookie "0.4.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.1" - encodeurl "~1.0.1" + depd "~1.1.2" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.1.0" + finalhandler "~1.1.2" fresh "0.5.2" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" - parseurl "~1.3.2" + parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.2" - qs "6.5.1" - range-parser "~1.2.0" - safe-buffer "5.1.1" - send "0.16.1" - serve-static "1.13.1" - setprototypeof "1.1.0" - statuses "~1.3.1" - type-is "~1.6.15" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - external-editor@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -2582,45 +2848,44 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -fastparse@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= dependencies: websocket-driver ">=0.5.1" faye-websocket@~0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== dependencies: websocket-driver ">=0.5.1" fbjs@^0.8.1, fbjs@^0.8.16: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" @@ -2628,66 +2893,58 @@ fbjs@^0.8.1, fbjs@^0.8.16: object-assign "^4.1.0" promise "^7.1.1" setimmediate "^1.0.5" - ua-parser-js "^0.7.9" + ua-parser-js "^0.7.18" figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= dependencies: flat-cache "^1.2.1" object-assign "^4.0.1" -file-loader@^1.1.6: +file-loader@^1.1.11: version "1.1.11" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" + integrity sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg== dependencies: loader-utils "^1.0.2" schema-utils "^0.4.5" -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" repeat-string "^1.6.1" to-regex-range "^2.1.0" -finalhandler@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== dependencies: debug "2.6.9" - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.3.1" + parseurl "~1.3.3" + statuses "~1.5.0" unpipe "~1.0.0" find-cache-dir@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= dependencies: commondir "^1.0.1" mkdirp "^0.5.1" @@ -2696,6 +2953,7 @@ find-cache-dir@^0.1.1: find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= dependencies: commondir "^1.0.1" make-dir "^1.0.0" @@ -2704,6 +2962,7 @@ find-cache-dir@^1.0.0: find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" @@ -2711,150 +2970,153 @@ find-up@^1.0.0: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flat-cache@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== dependencies: circular-json "^0.3.1" - del "^2.0.2" graceful-fs "^4.1.2" + rimraf "~2.6.2" write "^0.2.1" -flatten@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" - -flow-bin-loader@^1.0.2: +flow-bin-loader@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/flow-bin-loader/-/flow-bin-loader-1.0.3.tgz#1b95260437bea24786a5abc022ef3efa02df77c5" + integrity sha512-JgbydYGf7/Di8Jq4Az3+58g8lreabVdzI3IZQFICpQSH+yK8Uhgc1+Os5rnFBUfAQuhx3imUjpfOjaTLlz8M5A== flow-bin@^0.63.1: version "0.63.1" resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.63.1.tgz#ab00067c197169a5fb5b4996c8f6927b06694828" - -flow-typed@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.3.0.tgz#0f8604faab60691b885024e16ec0e3256e3b680e" - dependencies: - babel-polyfill "^6.26.0" - colors "^1.1.2" - fs-extra "^5.0.0" - github "0.2.4" - glob "^7.1.2" - got "^7.1.0" - md5 "^2.1.0" + integrity sha512-aWKHYs3UECgpwrIDVUiABjSC8dgaKmonymQDWO+6FhGcp9lnnxdDBE6Sfm3F7YaRPfLYsWAY4lndBrfrfyn+9g== + +flow-typed@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.2.tgz#967e83c762a1cbfcd52eebaece1ade77944f1714" + integrity sha512-RrHRmp/Bof1vDG1AqBcwuyxMMoezkl7TxvimA5c6GKZOOb1fkkRZ81S+1qAuvb4rUka5fLlFomKCnpMnCsgP+g== + dependencies: + "@babel/polyfill" "^7.0.0" + "@octokit/rest" "^15.12.1" + colors "^1.3.2" + fs-extra "^7.0.0" + glob "^7.1.3" + got "^8.3.2" + md5 "^2.2.1" mkdirp "^0.5.1" rimraf "^2.6.2" - semver "^5.5.0" - table "^4.0.2" + semver "^5.5.1" + table "^5.0.2" through "^2.3.8" - unzip "^0.1.11" - which "^1.3.0" - yargs "^4.2.0" + unzipper "^0.9.3" + which "^1.3.1" + yargs "^12.0.2" + +follow-redirects@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" + integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + dependencies: + debug "^3.2.6" font-awesome@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM= -for-in@^1.0.1, for-in@^1.0.2: +for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-extra@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" +from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" universalify "^0.1.0" +fs-minipass@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" + integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + dependencies: + minipass "^2.2.1" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.39" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -"fstream@>= 0.1.30 < 1": - version "0.1.31" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-0.1.31.tgz#7337f058fbbbbefa8c9f561a28cab0849202c988" +fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== dependencies: - graceful-fs "~3.0.2" - inherits "~2.0.0" - mkdirp "0.5" - rimraf "2" + nan "^2.12.1" + node-pre-gyp "^0.12.0" -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" +fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.1: +function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -2866,56 +3128,44 @@ gauge@~2.7.3: wide-align "^1.1.0" get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stream@^3.0.0: +get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -github@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/github/-/github-0.2.4.tgz#24fa7f0e13fa11b946af91134c51982a91ce538b" - dependencies: - mime "^1.2.11" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" +glob@^7.0.3, glob@^7.1.2, glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2927,36 +3177,25 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= dependencies: min-document "^2.19.0" process "~0.5.1" -globals@^11.0.1: - version "11.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" - -globals@^11.1.0: - version "11.5.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" +globals@^11.0.1, globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= dependencies: array-union "^1.0.1" glob "^7.0.3" @@ -2964,85 +3203,82 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" +got@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== dependencies: - decompress-response "^3.2.0" + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" duplexer3 "^0.1.4" get-stream "^3.0.0" - is-plain-obj "^1.1.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" isurl "^1.0.0-alpha5" lowercase-keys "^1.0.0" - p-cancelable "^0.3.0" - p-timeout "^1.1.1" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - url-parse-lax "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" url-to-options "^1.0.1" -graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graceful-fs@~3.0.2: - version "3.0.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" - dependencies: - natives "^1.1.0" - -handle-thing@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" +handle-thing@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" + integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== dependencies: has-symbol-support-x "^1.4.1" has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -3051,6 +3287,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -3059,173 +3296,202 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hash-base@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: - inherits "^2.0.1" + function-bind "^1.1.1" hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hawk@3.1.3, hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" + minimalistic-assert "^1.0.1" hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -hoist-non-react-statics@^2.3.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40" +hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" + integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.1" hosted-git-info@^2.1.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= dependencies: inherits "^2.0.1" obuf "^1.0.0" readable-stream "^2.0.1" wbuf "^1.1.0" -html-comment-regex@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" - html-entities@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= -http-errors@1.6.2, http-errors@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" +http-errors@1.7.2, http-errors@~1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== dependencies: - depd "1.1.1" + depd "~1.1.2" inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" -http-parser-js@>=0.4.0: +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +"http-parser-js@>=0.4.0 <0.4.11": version "0.4.10" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= -http-proxy-middleware@~0.17.4: - version "0.17.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== dependencies: - http-proxy "^1.16.2" - is-glob "^3.1.0" - lodash "^4.17.2" - micromatch "^2.3.11" + agent-base "4" + debug "3.1.0" -http-proxy@^1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" +http-proxy-middleware@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== dependencies: - eventemitter3 "1.x.x" - requires-port "1.x.x" + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" +http-proxy@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -hyphenate-style-name@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" +https-proxy-agent@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" -iconv-lite@0.4.19, iconv-lite@^0.4.17: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" +hyphenate-style-name@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" + integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== -iconv-lite@~0.4.13: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= -icss-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" +icss-utils@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== dependencies: - postcss "^6.0.1" + postcss "^7.0.14" ieee754@^1.1.4: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" ignore@^3.3.3: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== dependencies: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" @@ -3233,24 +3499,31 @@ import-local@^1.0.0: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indent-string@^2.1.0: - version "2.1.0" +indefinite-observable@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/indefinite-observable/-/indefinite-observable-1.0.2.tgz#0a328793ab2385d4b9dca23eaab4afe6936a73f8" + integrity sha512-Mps0898zEduHyPhb7UCgNmfzlqNZknVmaFz5qzr0mm04YQ5FGLhAyK/dJ+NaRxGyR6juQXIxh5Ev0xx+qq0nYA== + dependencies: + symbol-observable "1.2.0" + +indent-string@^2.1.0: + version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= dependencies: repeating "^2.0.0" indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -3258,18 +3531,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@^3.0.6: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -3289,90 +3566,109 @@ inquirer@^3.0.6: internal-ip@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" + integrity sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w= dependencies: meow "^3.3.0" interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" invariant@^2.2.0, invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" - -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" +ipaddr.js@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" + integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -3381,364 +3677,336 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-function@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" is-in-browser@^1.0.2, is-in-browser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" + integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - -is-odd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - dependencies: - is-number "^4.0.0" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: +is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-retry-allowed@^1.0.0: +is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + has-symbols "^1.0.0" is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= isomorphic-fetch@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= dependencies: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== dependencies: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -js-base64@^2.1.9: - version "2.4.3" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" - js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.9.1: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== dependencies: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= jsesc@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json3@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== -json5@^0.5.0, json5@^0.5.1: +json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - jss-camel-case@^6.0.0, jss-camel-case@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-6.1.0.tgz#ccb1ff8d6c701c02a1fed6fb6fb6b7896e11ce44" + integrity sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ== dependencies: hyphenate-style-name "^1.0.2" jss-compose@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-5.0.0.tgz#ce01b2e4521d65c37ea42cf49116e5f7ab596484" + integrity sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA== dependencies: warning "^3.0.0" jss-default-unit@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-8.0.2.tgz#cc1e889bae4c0b9419327b314ab1c8e2826890e6" + integrity sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg== -jss-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-5.1.0.tgz#b1ad74ec18631f34f65a2124fcfceb6400610e3d" +jss-expand@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-5.3.0.tgz#02be076efe650125c842f5bb6fb68786fe441ed6" + integrity sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg== jss-extend@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-6.2.0.tgz#4af09d0b72fb98ee229970f8ca852fec1ca2a8dc" + integrity sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA== dependencies: warning "^3.0.0" jss-global@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-3.0.0.tgz#e19e5c91ab2b96353c227e30aa2cbd938cdaafa2" + integrity sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q== jss-nested@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-6.0.1.tgz#ef992b79d6e8f63d939c4397b9d99b5cbbe824ca" + integrity sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA== dependencies: warning "^3.0.0" jss-preset-default@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-4.3.0.tgz#7bc91b0b282492557d36ed4e5c6d7c8cb3154bb8" + version "4.5.0" + resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-4.5.0.tgz#d3a457012ccd7a551312014e394c23c4b301cadd" + integrity sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ== dependencies: jss-camel-case "^6.1.0" jss-compose "^5.0.0" jss-default-unit "^8.0.2" - jss-expand "^5.1.0" + jss-expand "^5.3.0" jss-extend "^6.2.0" jss-global "^3.0.0" jss-nested "^6.0.1" @@ -3749,87 +4017,115 @@ jss-preset-default@^4.3.0: jss-props-sort@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-6.0.0.tgz#9105101a3b5071fab61e2d85ea74cc22e9b16323" + integrity sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g== jss-template@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jss-template/-/jss-template-1.0.1.tgz#09aed9d86cc547b07f53ef355d7e1777f7da430a" + integrity sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg== dependencies: warning "^3.0.0" jss-vendor-prefixer@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz#0166729650015ef19d9f02437c73667231605c71" + integrity sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA== dependencies: css-vendor "^0.3.8" -jss@^9.3.2, jss@^9.3.3: - version "9.8.0" - resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.0.tgz#77830def563870103f8671ed31ce3a3d2f32aa2b" +jss@^9.3.3, jss@^9.7.0: + version "9.8.7" + resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.7.tgz#ed9763fc0f2f0260fc8260dac657af61e622ce05" + integrity sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ== dependencies: is-in-browser "^1.1.3" symbol-observable "^1.1.0" warning "^3.0.0" -jsx-ast-utils@^2.0.0, jsx-ast-utils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" +jsx-ast-utils@^2.0.1, jsx-ast-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz#0ee4e2c971fb9601c67b5641b71be80faecf0b36" + integrity sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA== dependencies: array-includes "^3.0.3" keycode@^2.1.9: - version "2.1.9" - resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.9.tgz#964a23c54e4889405b4861a5c9f0480d45141dfa" + version "2.2.0" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" + integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ= + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" killable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lazy-cache@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" - dependencies: - set-getter "^0.1.0" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" +listenercount@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -3840,6 +4136,7 @@ load-json-file@^1.0.0: load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -3847,136 +4144,157 @@ load-json-file@^2.0.0: strip-bom "^3.0.0" loader-fs-cache@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc" + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" + integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw== dependencies: find-cache-dir "^0.1.1" mkdirp "0.5.1" loader-runner@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@^1.0.2, loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: - big.js "^3.1.3" + big.js "^5.2.2" emojis-list "^2.0.0" - json5 "^0.5.0" + json5 "^1.0.1" locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" path-exists "^3.0.0" -lodash.assign@^4.0.3, lodash.assign@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.3.0, lodash@~4.17.4: - version "4.17.5" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash@^4.17.4, lodash@^4.2.0: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.4: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== loglevel@^1.4.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" + version "1.6.3" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.3.tgz#77f2eb64be55a404c9fd04ad16d57c1d6d6b1280" + integrity sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA== longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: - js-tokens "^3.0.0" + js-tokens "^3.0.0 || ^4.0.0" loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= dependencies: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lowercase-keys@^1.0.0: +lowercase-keys@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" -macaddress@^0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" +macos-release@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" + integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" -"match-stream@>= 0.0.2 < 1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/match-stream/-/match-stream-0.0.2.tgz#99eb050093b34dffade421b9ac0b410a9cfa17cf" - dependencies: - buffers "~0.1.1" - readable-stream "~1.0.0" - -material-ui-icons@^1.0.0-beta.17: - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/material-ui-icons/-/material-ui-icons-1.0.0-beta.35.tgz#f795fafa385918ef7c88ee382e5e5bf4401f008c" +material-ui-icons@^1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/material-ui-icons/-/material-ui-icons-1.0.0-beta.36.tgz#86390a61f4c83f718eaba77ccce575834f2cf2a8" + integrity sha512-7rS6b2EV5QXCB/gTi/Ac9Wbxd+h9EZv1Td3rLLJe4IER8mVHRgdqZccB3EsjW2DrJ7opdY1+8X3/vyrS7CQNpg== dependencies: recompose "^0.26.0" -material-ui@^1.0.0-beta.30: - version "1.0.0-beta.35" - resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-1.0.0-beta.35.tgz#eeac6be307c0469943c7686e5c6bd4eaa6b1b563" +material-ui@^1.0.0-beta.47: + version "1.0.0-beta.47" + resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-1.0.0-beta.47.tgz#5deb97dc3e694299992d3c3cacb44051f8bc2166" + integrity sha512-SLyYStYSGrrhBtDQS6j2lpKeP3Nfi4vn+PA24xwuL+qSLJODD1EiQpn7w13Ky7Ni3M3Q1svBmHNnZLIKeOL85w== dependencies: + "@babel/runtime" "^7.0.0-beta.42" "@types/jss" "^9.3.0" - "@types/react-transition-group" "^2.0.6" - babel-runtime "^6.26.0" + "@types/react-transition-group" "^2.0.8" brcast "^3.0.1" classnames "^2.2.5" deepmerge "^2.0.1" dom-helpers "^3.2.1" - hoist-non-react-statics "^2.3.1" + hoist-non-react-statics "^2.5.0" jss "^9.3.3" jss-camel-case "^6.0.0" jss-default-unit "^8.0.2" @@ -3990,27 +4308,32 @@ material-ui@^1.0.0-beta.30: prop-types "^15.6.0" react-event-listener "^0.5.1" react-jss "^8.1.0" - react-popper "^0.8.0" + react-lifecycles-compat "^3.0.0" + react-popper "^0.10.0" react-scrollbar-size "^2.0.2" react-transition-group "^2.2.1" - recompose "^0.26.0" + recompose "^0.26.0 || ^0.27.0" scroll "^2.0.3" warning "^3.0.0" math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" + integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw= md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" -md5@^2.1.0: +md5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= dependencies: charenc "~0.0.1" crypt "~0.0.1" @@ -4019,16 +4342,28 @@ md5@^2.1.0: media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= dependencies: mimic-fn "^1.0.0" +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= dependencies: errno "^0.1.3" readable-stream "^2.0.1" @@ -4036,6 +4371,7 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= dependencies: camelcase-keys "^2.0.0" decamelize "^1.1.2" @@ -4051,32 +4387,17 @@ meow@^3.3.0: merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -micromatch@^3.1.4: - version "3.1.9" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.9.tgz#15dc93175ae39e52e93087847096effc73efcf89" +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4090,93 +4411,136 @@ micromatch@^3.1.4: object.pick "^1.3.0" regex-not "^1.0.0" snapdragon "^0.8.1" - to-regex "^3.0.1" + to-regex "^3.0.2" miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.33.0 < 2", mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" +mime-db@1.40.0, "mime-db@>= 1.40.0 < 2": + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" +mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== dependencies: - mime-db "~1.33.0" - -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + mime-db "1.40.0" -mime@^1.2.11, mime@^1.4.1, mime@^1.5.0: +mime@1.6.0, mime@^1.4.1, mime@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mimic-response@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= dependencies: dom-walk "^0.1.0" -minimalistic-assert@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minipass@^2.2.1, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= multicast-dns@^6.0.1: version "6.2.3" resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== dependencies: dns-packet "^1.3.1" thunky "^1.0.2" @@ -4184,21 +4548,23 @@ multicast-dns@^6.0.1: mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.3.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanomatch@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" define-property "^2.0.2" extend-shallow "^3.0.2" fragment-cache "^0.2.1" - is-odd "^2.0.0" is-windows "^1.0.2" kind-of "^6.0.2" object.pick "^1.3.0" @@ -4206,36 +4572,62 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -natives@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.1.tgz#011acce1f7cbd87f7ba6b3093d6cd9392be1c574" - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== neo-async@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f" + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== dependencies: encoding "^0.1.11" is-stream "^1.0.1" -node-forge@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" +node-fetch@^2.1.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + +node-forge@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" + integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== node-libs-browser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" browserify-zlib "^0.2.0" @@ -4244,10 +4636,10 @@ node-libs-browser@^2.0.0: constants-browserify "^1.0.0" crypto-browserify "^3.11.0" domain-browser "^1.1.1" - events "^1.0.0" + events "^3.0.0" https-browserify "^1.0.0" os-browserify "^0.3.0" - path-browserify "0.0.0" + path-browserify "0.0.1" process "^0.11.10" punycode "^1.2.4" querystring-es3 "^0.2.0" @@ -4258,165 +4650,194 @@ node-libs-browser@^2.0.0: timers-browserify "^2.0.4" tty-browserify "0.0.0" url "^0.11.0" - util "^0.10.3" - vm-browserify "0.0.4" + util "^0.11.0" + vm-browserify "^1.0.1" -node-pre-gyp@^0.6.39: - version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" - hawk "3.1.3" mkdirp "^0.5.1" + needle "^2.2.1" nopt "^4.0.1" + npm-packlist "^1.1.6" npmlog "^4.0.2" - rc "^1.1.7" - request "2.81.0" + rc "^1.2.7" rimraf "^2.6.1" semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" + tar "^4" nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" + resolve "^1.10.0" semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-scroll-left@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-scroll-left/-/normalize-scroll-left-0.1.2.tgz#6b79691ba79eb5fb107fa5edfbdc06b55caee2aa" + integrity sha512-F9YMRls0zCF6BFIE2YnXDRpHPpfd91nOIaNdDgrx5YMoPLo8Wqj+6jNXHQsYBavJeXP4ww8HCt0xQAKc5qk2Fg== -normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" gauge "~2.7.3" set-blocking "~2.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" object-hash@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b" + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" +object.fromentries@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" + integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA== dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" + define-properties "^1.1.2" + es-abstract "^1.11.0" + function-bind "^1.1.1" + has "^1.0.1" object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" -obuf@^1.0.0, obuf@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.3: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" opn@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.2.0.tgz#71fdf934d6827d676cecbea1531f95d354641225" + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== dependencies: is-wsl "^1.1.0" optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -4426,160 +4847,228 @@ optionator@^0.8.2: wordwrap "~1.0.0" original@>=0.0.5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== dependencies: - url-parse "1.0.x" + url-parse "^1.4.3" os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-locale@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= dependencies: lcid "^1.0.0" os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== dependencies: execa "^0.7.0" lcid "^1.0.0" mem "^1.1.0" +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-name@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" + integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== + dependencies: + macos-release "^2.2.0" + windows-release "^3.1.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -"over@>= 0.0.5 < 1": - version "0.0.5" - resolved "https://registry.yarnpkg.com/over/-/over-0.0.5.tgz#f29852e70fd7e25f360e013a8ec44c82aedb5708" +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== -p-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== dependencies: p-finally "^1.0.0" p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== parse-asn1@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" + safe-buffer "^5.1.1" parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: error-ex "^1.2.0" -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -4588,19 +5077,22 @@ path-type@^1.0.0: path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= dependencies: pify "^2.0.0" path@^0.12.7: version "0.12.7" resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= dependencies: process "^0.11.1" util "^0.10.3" pbkdf2@^3.0.3: - version "3.0.14" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -4608,55 +5100,61 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= dependencies: find-up "^1.0.0" pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= dependencies: find-up "^2.1.0" pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== -popper.js@^1.12.9: - version "1.12.9" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.12.9.tgz#0dfbc2dff96c451bb332edcfcfaaf566d331d5b3" +popper.js@^1.14.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" + integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== portfinder@^1.0.9: - version "1.0.13" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw== dependencies: async "^1.5.2" debug "^2.2.0" @@ -4665,444 +5163,266 @@ portfinder@^1.0.9: posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" - dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" - -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" - dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" - -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== dependencies: - postcss "^5.0.14" + postcss "^7.0.5" -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" +postcss-modules-local-by-default@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" + integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== dependencies: - postcss "^5.0.4" + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-value-parser "^3.3.1" -postcss-discard-empty@^2.0.1: +postcss-modules-scope@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz#ad3f5bf7856114f6fcab901b0502e2a2bc39d4eb" + integrity sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A== dependencies: - postcss "^5.0.14" + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - dependencies: - postcss "^5.0.16" - -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" - dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c" - dependencies: - postcss "^5.0.4" - uniqid "^4.0.0" - -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" - dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" - -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" - dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" - dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" - vendors "^1.0.0" - -postcss-message-helpers@^2.0.0: +postcss-modules-values@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" - -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" - dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" - dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" - -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" - -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" - dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - -postcss-modules-extract-imports@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" - dependencies: - postcss "^6.0.1" - -postcss-modules-local-by-default@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-scope@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-values@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" + integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== dependencies: icss-replace-symbols "^1.1.0" - postcss "^6.0.1" - -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" - dependencies: - postcss "^5.0.5" - -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" - -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" - dependencies: - postcss "^5.0.4" - -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" - dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" + postcss "^7.0.6" -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" +postcss-selector-parser@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== dependencies: - flatten "^1.0.2" + cssesc "^3.0.0" indexes-of "^1.0.1" uniq "^1.0.1" -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" - dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" - -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" - dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" +postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss@^6.0.1: - version "6.0.19" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.19.tgz#76a78386f670b9d9494a655bf23ac012effd1555" +postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.17" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" + integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== dependencies: - chalk "^2.3.1" + chalk "^2.4.2" source-map "^0.6.1" - supports-color "^5.2.0" + supports-color "^6.1.0" prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0, prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== process@^0.11.1, process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= progress@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== dependencies: asap "~2.0.3" -prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0: - version "15.6.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" +prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== dependencies: - fbjs "^0.8.16" - loose-envify "^1.3.1" + loose-envify "^1.4.0" object-assign "^4.1.1" + react-is "^16.8.1" -proxy-addr@~2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" +proxy-addr@~2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" + integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== dependencies: forwarded "~0.1.2" - ipaddr.js "1.6.0" + ipaddr.js "1.9.0" prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= public-encrypt@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" browserify-rsa "^4.0.0" create-hash "^1.1.0" parse-asn1 "^5.0.0" randombytes "^2.0.1" + safe-buffer "^5.1.2" -"pullstream@>= 0.4.1 < 1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/pullstream/-/pullstream-0.4.1.tgz#d6fb3bf5aed697e831150eb1002c25a3f8ae1314" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: - over ">= 0.0.5 < 1" - readable-stream "~1.0.31" - setimmediate ">= 1.0.2 < 2" - slice-stream ">= 1.0.0 < 2" + end-of-stream "^1.1.0" + once "^1.3.1" punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - -qs@6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== dependencies: + decode-uri-component "^0.2.0" object-assign "^4.1.0" strict-uri-encode "^1.0.0" querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@0.0.x: - version "0.0.4" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" - -querystringify@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== -raf@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575" +raf@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== dependencies: performance-now "^2.1.0" rafl@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/rafl/-/rafl-1.2.2.tgz#fe930f758211020d47e38815f5196a8be4150740" + integrity sha1-/pMPdYIRAg1H44gV9Rlqi+QVB0A= dependencies: global "~4.3.0" -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@^1.0.3, range-parser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" +range-parser@^1.0.3, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== dependencies: - bytes "3.0.0" - http-errors "1.6.2" - iconv-lite "0.4.19" + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.1.7: - version "1.2.5" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: - deep-extend "~0.4.0" + deep-extend "^0.6.0" ini "~1.3.0" minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^16.2.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.0.tgz#099f067dd5827ce36a29eaf9a6cdc7cbf6216b1e" +react-dom@^16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" + integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" + prop-types "^15.6.2" + scheduler "^0.13.6" react-event-listener@^0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.3.tgz#a8b492596ad601865314fcc2c18cb87b6ce3876e" + version "0.5.10" + resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.10.tgz#378403c555fe616f312891507a742ecbbe2c90de" + integrity sha512-YZklRszh9hq3WP3bdNLjFwJcTCVe7qyTf5+LWNaHfZQaZrptsefDK2B5HHpOsEEaMHvjllUPr0+qIFVTSsurow== dependencies: - babel-runtime "^6.26.0" + "@babel/runtime" "7.0.0-beta.42" fbjs "^0.8.16" prop-types "^15.6.0" warning "^3.0.0" @@ -5110,74 +5430,94 @@ react-event-listener@^0.5.1: react-fa@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/react-fa/-/react-fa-5.0.0.tgz#d571732856c6cb2c155c46daef018ba67a75b973" + integrity sha512-pBEJigNkDJPAP/P9mQXT55VbJbbtwqi4ayieXuFvGpd+gl3aZ9IbjjVKJihdhdysJP0XRgrSa3sT3yOmkQi8wQ== dependencies: font-awesome "^4.3.0" prop-types "^15.5.8" +react-is@^16.8.1: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + react-jss@^8.1.0: - version "8.3.3" - resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-8.3.3.tgz#677a57569d3e4f5099fcdeafeddd8d2c62ab5977" + version "8.6.1" + resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-8.6.1.tgz#a06e2e1d2c4d91b4d11befda865e6c07fbd75252" + integrity sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ== dependencies: - hoist-non-react-statics "^2.3.1" - jss "^9.3.2" + hoist-non-react-statics "^2.5.0" + jss "^9.7.0" jss-preset-default "^4.3.0" prop-types "^15.6.0" theming "^1.3.0" -react-popper@^0.8.0: - version "0.8.2" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.8.2.tgz#092095ff13933211d3856d9f325511ec3a42f12c" +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-popper@^0.10.0: + version "0.10.4" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.10.4.tgz#af2a415ea22291edd504678d7afda8a6ee3295aa" + integrity sha1-rypBXqIike3VBGeNev2opu4ylao= dependencies: - popper.js "^1.12.9" - prop-types "^15.6.0" + popper.js "^1.14.1" + prop-types "^15.6.1" -react-resize-detector@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-1.1.0.tgz#4a9831fa3caad32230478dd0185cbd2aa91a5ebf" +react-resize-detector@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-2.3.0.tgz#57bad1ae26a28a62a2ddb678ba6ffdf8fa2b599c" + integrity sha512-oCAddEWWeFWYH5FAcHdBYcZjAw9fMzRUK9sWSx6WvSSOPVRxcHd5zTIGy/mOus+AhN/u6T4TMiWxvq79PywnJQ== dependencies: - prop-types "^15.5.10" + lodash.debounce "^4.0.8" + lodash.throttle "^4.1.1" + prop-types "^15.6.0" + resize-observer-polyfill "^1.5.0" react-scrollbar-size@^2.0.2: version "2.1.0" resolved "https://registry.yarnpkg.com/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz#105e797135cab92b1f9e16f00071db7f29f80754" + integrity sha512-9dDUJvk7S48r0TRKjlKJ9e/LkLLYgc9LdQR6W21I8ZqtSrEsedPOoMji4nU3DHy7fx2l8YMScJS/N7qiloYzXQ== dependencies: babel-runtime "^6.26.0" prop-types "^15.6.0" react-event-listener "^0.5.1" stifle "^1.0.2" -react-smooth@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-1.0.0.tgz#b29dbebddddb06d21b5b08962167fb9eac1897d8" +react-smooth@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-1.0.2.tgz#f7a2d932ece8db898646078c3c97f3e9533e0486" + integrity sha512-pIGzL1g9VGAsRsdZQokIK0vrCkcdKtnOnS1gyB2rrowdLy69lNSWoIjCTWAfgbiYvria8tm5hEZqj+jwXMkV4A== dependencies: lodash "~4.17.4" prop-types "^15.6.0" - raf "^3.2.0" - react-transition-group "^2.2.1" + raf "^3.4.0" + react-transition-group "^2.5.0" -react-transition-group@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" +react-transition-group@^2.2.1, react-transition-group@^2.5.0, react-transition-group@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== dependencies: - chain-function "^1.0.0" - classnames "^2.2.5" - dom-helpers "^3.2.0" - loose-envify "^1.3.1" - prop-types "^15.5.8" - warning "^3.0.0" + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" -react@^16.2.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" +react@^16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" + prop-types "^15.6.2" + scheduler "^0.13.6" read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= dependencies: find-up "^1.0.0" read-pkg "^1.0.0" @@ -5185,6 +5525,7 @@ read-pkg-up@^1.0.1: read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= dependencies: find-up "^2.0.0" read-pkg "^2.0.0" @@ -5192,6 +5533,7 @@ read-pkg-up@^2.0.0: read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -5200,92 +5542,101 @@ read-pkg@^1.0.0: read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= dependencies: load-json-file "^2.0.0" normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readable-stream@^2.2.9: - version "2.3.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" isarray "~1.0.0" process-nextick-args "~2.0.0" safe-buffer "~5.1.1" - string_decoder "~1.0.3" + string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@~1.0.0, readable-stream@~1.0.31: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" +readable-stream@^3.0.6: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" -recharts-scale@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.3.2.tgz#dac7621714a4765d152cb2adbc30c73b831208c9" +recharts-scale@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.2.tgz#b66315d985cd9b80d5f7d977a5aab9a305abc354" + integrity sha512-p/cKt7j17D1CImLgX2f5+6IXLbRHGUQkogIp06VUoci/XkhOQiGSzUrsD1uRmiI7jha4u8XNFOjkHkzzBPivMg== + dependencies: + decimal.js-light "^2.4.1" -recharts@^1.0.0-beta.9: - version "1.0.0-beta.10" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-1.0.0-beta.10.tgz#d3cd15df6b7879d5968da3c942b5fcdaf2504fe1" +recharts@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-1.6.2.tgz#4ced884f04b680e8dac5d3e109f99b0e7cfb9b0f" + integrity sha512-NqVN8Hq5wrrBthTxQB+iCnZjup1dc+AYRIB6Q9ck9UjdSJTt4PbLepGpudQEYJEN5iIpP/I2vThC4uiTJa7xUQ== dependencies: - classnames "2.2.5" - core-js "2.5.1" - d3-interpolate "^1.1.5" - d3-scale "1.0.6" - d3-shape "1.2.0" - lodash "~4.17.4" + classnames "^2.2.5" + core-js "^2.5.1" + d3-interpolate "^1.3.0" + d3-scale "^2.1.0" + d3-shape "^1.2.0" + lodash "^4.17.5" prop-types "^15.6.0" - react-resize-detector "1.1.0" - react-smooth "1.0.0" - recharts-scale "0.3.2" - reduce-css-calc "1.3.0" + react-resize-detector "^2.3.0" + react-smooth "^1.0.0" + recharts-scale "^0.4.2" + reduce-css-calc "^1.3.0" recompose@^0.26.0: version "0.26.0" resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.26.0.tgz#9babff039cb72ba5bd17366d55d7232fbdfb2d30" + integrity sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog== + dependencies: + change-emitter "^0.1.2" + fbjs "^0.8.1" + hoist-non-react-statics "^2.3.1" + symbol-observable "^1.0.4" + +"recompose@^0.26.0 || ^0.27.0": + version "0.27.1" + resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.27.1.tgz#1a49e931f183634516633bbb4f4edbfd3f38a7ba" + integrity sha512-p7xsyi/rfNjHfdP7vPU02uSFa+Q1eHhjKrvO+3+kRP4Ortj+MxEmpmd+UQtBGM2D2iNAjzNI5rCyBKp9Ob5McA== dependencies: + babel-runtime "^6.26.0" change-emitter "^0.1.2" fbjs "^0.8.1" hoist-non-react-statics "^2.3.1" + react-lifecycles-compat "^3.0.2" symbol-observable "^1.0.4" redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= dependencies: indent-string "^2.1.0" strip-indent "^1.0.1" -reduce-css-calc@1.3.0, reduce-css-calc@^1.2.6: +reduce-css-calc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= dependencies: balanced-match "^0.4.2" math-expression-evaluator "^1.2.14" @@ -5294,53 +5645,51 @@ reduce-css-calc@1.3.0, reduce-css-calc@^1.2.6: reduce-function-call@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" + integrity sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk= dependencies: balanced-match "^0.4.2" regenerate@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" - -regenerator-runtime@^0.10.5: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.11.0: +regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpu-core@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= dependencies: regenerate "^1.2.1" regjsgen "^0.2.0" @@ -5349,104 +5698,105 @@ regexpu-core@^2.0.0: regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= regjsparser@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" -request@2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" -requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: +requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resize-observer-polyfill@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= dependencies: resolve-from "^3.0.0" resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.5.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" + integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -5454,114 +5804,150 @@ restore-cursor@^2.0.0: ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" +rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: - glob "^7.0.5" + glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: - hash-base "^2.0.0" + hash-base "^3.0.0" inherits "^2.0.1" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" rx-lite-aggregates@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= dependencies: rx-lite "*" rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= -safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@~1.2.1: +sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scheduler@^0.13.6: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" schema-utils@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + integrity sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8= dependencies: ajv "^5.0.0" schema-utils@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== dependencies: ajv "^6.1.0" + ajv-errors "^1.0.0" ajv-keywords "^3.1.0" scroll@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/scroll/-/scroll-2.0.3.tgz#0951b785544205fd17753bc3d294738ba16fc2ab" + integrity sha512-3ncZzf8gUW739h3LeS68nSssO60O+GGjT3SxzgofQmT8PIoyHzebql9HHPJopZX8iT6TKOdwaWFMqL6LzUN3DQ== dependencies: rafl "~1.2.1" select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^1.9.1: - version "1.10.2" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.2.tgz#b4449580d99929b65b10a48389301a6592088758" + version "1.10.4" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" + integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== dependencies: - node-forge "0.7.1" + node-forge "0.7.5" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -send@0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== dependencies: debug "2.6.9" - depd "~1.1.1" + depd "~1.1.2" destroy "~1.0.4" - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.3.1" + range-parser "~1.2.1" + statuses "~1.5.0" -serve-index@^1.7.2: +serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= dependencies: accepts "~1.3.4" batch "0.6.1" @@ -5571,32 +5957,25 @@ serve-index@^1.7.2: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== dependencies: - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" - parseurl "~1.3.2" - send "0.16.1" + parseurl "~1.3.3" + send "0.17.1" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-getter@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" - dependencies: - to-object-path "^0.3.0" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5606,27 +5985,32 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" is-plain-object "^2.0.3" split-string "^3.0.1" -"setimmediate@>= 1.0.1 < 2", "setimmediate@>= 1.0.2 < 2", setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.4, setimmediate@^1.0.5, setimmediate@~1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - -setprototypeof@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.10" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b" + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -5634,36 +6018,45 @@ sha.js@^2.4.0, sha.js@^2.4.8: shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== dependencies: is-fullwidth-code-point "^2.0.0" -"slice-stream@>= 1.0.0 < 2": - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-stream/-/slice-stream-1.0.0.tgz#5b33bd66f013b1a7f86460b03d463dec39ad3ea0" +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: - readable-stream "~1.0.31" + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -5672,12 +6065,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370" + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -5686,17 +6081,12 @@ snapdragon@^0.8.1: map-cache "^0.2.2" source-map "^0.5.6" source-map-resolve "^0.5.0" - use "^2.0.0" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" + use "^3.1.0" -sockjs-client@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" +sockjs-client@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.5.tgz#1bb7c0f7222c40f42adf14f4442cbd1269771a83" + integrity sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM= dependencies: debug "^2.6.6" eventsource "0.1.6" @@ -5708,25 +6098,29 @@ sockjs-client@1.1.4: sockjs@0.3.19: version "0.3.19" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== dependencies: faye-websocket "^0.10.0" uuid "^3.0.1" -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= dependencies: is-plain-obj "^1.0.0" source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: - atob "^2.0.0" + atob "^2.1.1" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" @@ -5735,198 +6129,222 @@ source-map-resolve@^0.5.0: source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== dependencies: source-map "^0.5.6" source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdx-correct@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== spdx-expression-parse@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== -spdy-transport@^2.0.18: - version "2.0.20" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.20.tgz#735e72054c486b2354fe89e702256004a39ace4d" +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== dependencies: - debug "^2.6.8" - detect-node "^2.0.3" + debug "^4.1.0" + detect-node "^2.0.4" hpack.js "^2.1.6" - obuf "^1.1.1" - readable-stream "^2.2.9" - safe-buffer "^5.0.1" - wbuf "^1.7.2" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" -spdy@^3.4.1: - version "3.4.7" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" +spdy@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52" + integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q== dependencies: - debug "^2.6.8" - handle-thing "^1.2.5" + debug "^4.1.0" + handle-thing "^2.0.0" http-deceiver "^1.2.7" - safe-buffer "^5.0.1" select-hose "^2.0.0" - spdy-transport "^2.0.18" + spdy-transport "^3.0.0" split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2": - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - -statuses@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= stifle@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/stifle/-/stifle-1.0.4.tgz#8b3bcdf52419b0a9c79e35adadce50123c1d8e99" + version "1.1.0" + resolved "https://registry.yarnpkg.com/stifle/-/stifle-1.1.0.tgz#1680b5de9de04074164f4ac0fe7d34db6b6f7229" + integrity sha1-FoC13p3gQHQWT0rA/n0022tvcik= stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" readable-stream "^2.0.2" stream-http@^2.7.2: - version "2.8.0" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10" + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" - readable-stream "^2.3.3" + readable-stream "^2.3.6" to-arraybuffer "^1.0.0" xtend "^4.0.0" strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0, string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== dependencies: - safe-buffer "~5.1.0" + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= dependencies: is-utf8 "^0.2.0" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= dependencies: get-stdin "^4.0.1" strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= style-loader@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.1.tgz#591ffc80bcefe268b77c5d9ebc0505d772619f85" + integrity sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og== dependencies: loader-utils "^1.0.2" schema-utils "^0.3.0" @@ -5934,50 +6352,38 @@ style-loader@^0.19.1: supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^4.2.1: version "4.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= dependencies: has-flag "^2.0.0" -supports-color@^5.1.0, supports-color@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" +supports-color@^5.1.0, supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^5.3.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== dependencies: has-flag "^3.0.0" -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" - dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" - -symbol-observable@^1.0.4, symbol-observable@^1.1.0: +symbol-observable@1.2.0, symbol-observable@^1.0.4, symbol-observable@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== dependencies: ajv "^5.2.3" ajv-keywords "^2.1.0" @@ -5986,49 +6392,43 @@ table@4.0.2: slice-ansi "1.0.0" string-width "^2.1.1" -table@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" +table@^5.0.2: + version "5.4.1" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.1.tgz#0691ae2ebe8259858efb63e550b6d5f9300171e8" + integrity sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w== dependencies: - ajv "^6.0.1" - ajv-keywords "^3.0.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" tapable@^0.2.7: - version "0.2.8" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" - -tar-pack@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" + version "0.2.9" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.9.tgz#af2d8bbc9b04f74ee17af2b4d9048f807acd18a8" + integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== + +tar@^4: + version "4.4.10" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" + integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.5" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= theming@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/theming/-/theming-1.3.0.tgz#286d5bae80be890d0adc645e5ca0498723725bdc" + integrity sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw== dependencies: brcast "^3.0.1" is-function "^1.0.1" @@ -6038,121 +6438,136 @@ theming@^1.3.0: through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= thunky@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" + version "1.0.3" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" + integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== time-stamp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" + version "2.2.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.2.0.tgz#917e0a66905688790ec7bbbde04046259af83f57" + integrity sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA== -timed-out@^4.0.0: +timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= timers-browserify@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae" + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== dependencies: setimmediate "^1.0.4" tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" -to-regex@^3.0.1: +to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@~2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - dependencies: - punycode "^1.4.1" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== "traverse@>=0.3.0 <0.4": version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" -type-is@~1.6.15: - version "1.6.16" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" - mime-types "~2.1.18" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/type/-/type-1.0.1.tgz#084c9a17fcc9151a2cdb1459905c2e45e4bb7d61" + integrity sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw== typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -ua-parser-js@^0.7.9: - version "0.7.18" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed" +ua-parser-js@^0.7.18: + version "0.7.20" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" + integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -6162,22 +6577,21 @@ uglify-js@^2.8.29: uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + integrity sha1-uVH0q7a9YX5m9j64kUmOORdj4wk= dependencies: source-map "^0.5.6" uglify-js "^2.8.29" webpack-sources "^1.0.1" -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -6187,119 +6601,152 @@ union-value@^1.0.0: uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= -uniqid@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1" +universal-user-agent@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4" + integrity sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q== dependencies: - macaddress "^0.2.8" - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + os-name "^3.0.0" universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" -unzip@^0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/unzip/-/unzip-0.1.11.tgz#89749c63b058d7d90d619f86b98aa1535d3b97f0" - dependencies: - binary ">= 0.3.0 < 1" - fstream ">= 0.1.30 < 1" - match-stream ">= 0.0.2 < 1" - pullstream ">= 0.4.1 < 1" - readable-stream "~1.0.31" - setimmediate ">= 1.0.1 < 2" +unzipper@^0.9.3: + version "0.9.15" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.9.15.tgz#97d99203dad17698ee39882483c14e4845c7549c" + integrity sha512-2aaUvO4RAeHDvOCuEtth7jrHFaCKTSXPqUkXwADaLBzGbgZGzUDccoEdJ5lW+3RmfpOZYNx0Rw6F6PUzM6caIA== + dependencies: + big-integer "^1.6.17" + binary "~0.3.0" + bluebird "~3.4.1" + buffer-indexof-polyfill "~1.0.0" + duplexer2 "~0.1.4" + fstream "^1.0.12" + listenercount "~1.0.1" + readable-stream "~2.3.6" + setimmediate "~1.0.4" + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== -upath@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d" +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-loader@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.6.2.tgz#a007a7109620e9d988d14bce677a1decb9a993f7" + integrity sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q== dependencies: loader-utils "^1.0.2" mime "^1.4.1" schema-utils "^0.3.0" -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= dependencies: - prepend-http "^1.0.1" + prepend-http "^2.0.0" -url-parse@1.0.x: - version "1.0.5" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" +url-parse@^1.1.8, url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== dependencies: - querystringify "0.0.x" - requires-port "1.0.x" + querystringify "^2.1.1" + requires-port "^1.0.0" -url-parse@^1.1.8: - version "1.2.0" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" - dependencies: - querystringify "~1.0.0" - requires-port "~1.0.0" +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= dependencies: punycode "1.3.2" querystring "0.2.0" -use@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8" - dependencies: - define-property "^0.2.5" - isobject "^3.0.0" - lazy-cache "^2.0.2" +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@0.10.3, util@^0.10.3: +util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.0.0, uuid@^3.0.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" +uuid@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== validate-npm-package-license@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" @@ -6307,48 +6754,40 @@ validate-npm-package-license@^3.0.1: vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vm-browserify@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" - dependencies: - indexof "0.0.1" +vm-browserify@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" + integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== warning@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= dependencies: loose-envify "^1.0.0" watchpack@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed" + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== dependencies: chokidar "^2.0.2" graceful-fs "^4.1.2" neo-async "^2.5.0" -wbuf@^1.1.0, wbuf@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== dependencies: minimalistic-assert "^1.0.0" webpack-dev-middleware@1.12.2: version "1.12.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" + integrity sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A== dependencies: memory-fs "~0.4.1" mime "^1.5.0" @@ -6356,21 +6795,22 @@ webpack-dev-middleware@1.12.2: range-parser "^1.0.3" time-stamp "^2.0.0" -webpack-dev-server@^2.11.1: - version "2.11.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz#1f4f4c78bf1895378f376815910812daf79a216f" +webpack-dev-server@^2.11.5: + version "2.11.5" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.11.5.tgz#416fbdea0e04eebe44a626e791d5a2eb37fe8c48" + integrity sha512-7TdOKKt7G3sWEhPKV0zP+nD0c4V9YKUJ3wDdBwQsZNo58oZIRoVIu66pg7PYkBW8A74msP9C2kLwmxGHndz/pw== dependencies: ansi-html "0.0.7" array-includes "^3.0.3" bonjour "^3.5.0" - chokidar "^2.0.0" - compression "^1.5.2" + chokidar "^2.1.2" + compression "^1.7.3" connect-history-api-fallback "^1.3.0" debug "^3.1.0" del "^3.0.0" express "^4.16.2" html-entities "^1.2.0" - http-proxy-middleware "~0.17.4" + http-proxy-middleware "^0.19.1" import-local "^1.0.0" internal-ip "1.2.0" ip "^1.1.5" @@ -6379,25 +6819,27 @@ webpack-dev-server@^2.11.1: opn "^5.1.0" portfinder "^1.0.9" selfsigned "^1.9.1" - serve-index "^1.7.2" + serve-index "^1.9.1" sockjs "0.3.19" - sockjs-client "1.1.4" - spdy "^3.4.1" + sockjs-client "1.1.5" + spdy "^4.0.0" strip-ansi "^3.0.0" supports-color "^5.1.0" webpack-dev-middleware "1.12.2" yargs "6.6.0" webpack-sources@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== dependencies: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^3.10.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894" +webpack@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.12.0.tgz#3f9e34360370602fcf639e97939db486f4ec0d74" + integrity sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ== dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -6423,63 +6865,74 @@ webpack@^3.10.0: yargs "^8.0.2" websocket-driver@>=0.5.1: - version "0.7.0" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== dependencies: - http-parser-js ">=0.4.0" + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== whatwg-fetch@>=0.10.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.9, which@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" +which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: - string-width "^1.0.2" + string-width "^1.0.2 || 2" window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" +windows-release@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" + integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== + dependencies: + execa "^1.0.0" wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -6487,47 +6940,66 @@ wrap-ansi@^2.0.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= dependencies: mkdirp "^0.5.1" xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +"y18n@^3.2.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" +yallist@^3.0.0, yallist@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" + camelcase "^5.0.0" + decamelize "^1.2.0" yargs-parser@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= dependencies: camelcase "^3.0.0" yargs-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= dependencies: camelcase "^4.1.0" yargs@6.6.0: version "6.6.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= dependencies: camelcase "^3.0.0" cliui "^3.2.0" @@ -6543,28 +7015,28 @@ yargs@6.6.0: y18n "^3.2.1" yargs-parser "^4.2.0" -yargs@^4.2.0: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" +yargs@^12.0.2: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + os-locale "^3.0.0" require-directory "^2.1.1" require-main-filename "^1.0.1" set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= dependencies: camelcase "^4.1.0" cliui "^3.2.0" @@ -6583,6 +7055,7 @@ yargs@^8.0.2: yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= dependencies: camelcase "^1.0.2" cliui "^2.1.0" diff --git a/docs/Cakeshop/Cakeshop FAQ.md b/docs/Cakeshop/Cakeshop FAQ.md new file mode 100644 index 0000000000..7c86278650 --- /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 0000000000..017a0df85c --- /dev/null +++ b/docs/Cakeshop/Getting started.md @@ -0,0 +1,159 @@ +## 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: + + ``` + geth.auto.start=false + geth.auto.stop=false + ``` + +4. Run: + + ``` + $ java -jar cakeshop.war + ``` + +5. Open **http://localhost:8080/** in your browser (Firefox/Chrome supported) + +6. The dropdown menu on the top right of the page should show "Manage Nodes" if you haven't attached to any yet. Click on that to go to the Manage Nodes page. + +7. Click Add Node and input the RPC url of your Quorum node (i.e. http://localhost:22000) and the path to the Tessera P2P Party Info endpoint (i.e. http://localhost:9001/partyinfo). + +8. Once added, click on View to attach to the node and return to the main Cakeshop page + +### 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 0000000000..75d5d22454 --- /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](https://github.com/jpmorganchase/cakeshop/blob/master/docs/configuration.md#custom-quorum-binaries)) diff --git a/docs/Cakeshop/console.png b/docs/Cakeshop/console.png new file mode 100644 index 0000000000..7694032d29 Binary files /dev/null and b/docs/Cakeshop/console.png differ diff --git a/docs/Consensus/Consensus.md b/docs/Consensus/Consensus.md index fa1b2871f6..97857c83d0 100644 --- a/docs/Consensus/Consensus.md +++ b/docs/Consensus/Consensus.md @@ -5,7 +5,7 @@ With no need for POW/POS in a permissioned network, Quorum instead offers multip * __Raft-based Consensus__: A consensus model for faster blocktimes, transaction finality, and on-demand block creation. See [Raft-based consensus for Ethereum/Quorum](../raft) for more information -* __Istanbul BFT (Byzantine Fault Tolerance) Consensus__: A PBFT-inspired consensus algorithm with transaction finality, by AMIS. See [Istanbul BFT Consensus documentation](https://github.com/ethereum/EIPs/issues/650), the [RPC API](../istanbul-rpc-api), and this [technical web article](https://medium.com/getamis/istanbul-bft-ibft-c2758b7fe6ff) for more information +* __Istanbul BFT (Byzantine Fault Tolerance) Consensus__: A PBFT-inspired consensus algorithm with transaction finality, by AMIS. See [Istanbul BFT Consensus documentation](https://github.com/ethereum/EIPs/issues/650), the [RPC API](../ibft/istanbul-rpc-api.md), and this [technical web article](https://medium.com/getamis/istanbul-bft-ibft-c2758b7fe6ff) for more information * __Clique POA Consensus__: a default POA consensus algorithm bundled with Go Ethereum. See [Clique POA Consensus Documentation](https://github.com/ethereum/EIPs/issues/225) and a [guide to setup clique json](https://hackernoon.com/hands-on-creating-your-own-local-private-geth-node-beginner-friendly-3d45902cc612) with [puppeth](https://blog.ethereum.org/2017/04/14/geth-1-6-puppeth-master/) diff --git a/docs/Consensus/ibft/ibft-parameters.md b/docs/Consensus/ibft/ibft-parameters.md new file mode 100644 index 0000000000..98028a4ff3 --- /dev/null +++ b/docs/Consensus/ibft/ibft-parameters.md @@ -0,0 +1,69 @@ +# IBFT parameters + +## CLI options + +### Block period + +`--istanbul.blockperiod 1` + +Setting the block period is used for how long blocks should be minted by the validators. It is also used for validation +of block times by all nodes, so should not be changed after deciding a value for the network. +The setting is a positive integer, and measures the minimum numbers of seconds before the next block is considered +valid. + +The default value is `1`. + +### Request timeout + +`--istanbul.requesttimeout 10000` + +The request timeout is the timeout at which IBFT will seek to trigger a new round if the previous one did not complete. +This period increases are the timeout is hit more often. This parameter sets the minimum timeout in the case of normal +operation and is measured in milliseconds. + +The default value is `10000`. + +## Genesis file options + +Within the `genesis.json` file, there is an area for IBFT specific configuration, much like a Clique network +configuration. + +The options are as follows: +``` +{ + "config": { + "istanbul": { + "epoch": 30000, + "policy": 0, + "ceil2Nby3Block": 0 + }, + ... + }, + ... +} +``` + +### Epoch + +The epoch specifies the number of blocks that should pass before pending validator votes are reset. When the +`blocknumber%EPOCH == 0`, the votes are reset in order to prevent a single vote from becoming stale. If the existing +vote was still due to take place, then it must be resubmitted, along with all its votes. + +### Policy + +The policy refers to the proposer selection policy, which is either `ROUND_ROBIN` or `STICKY`. + +A value of `0` denotes a `ROUND_ROBIN` policy, where the next expected proposer is the next in queue. Once a proposer +has submitted a valid block, they join the back of the queue and must wait their turn again. + +A value of `1` denotes a `STICKY` proposer policy, where a single proposer is selected to mint blocks and does so until +such a time as they go offline or are otherwise unreachable. + +### ceil2Nby3Block + +The `ceil2Nby3Block` sets the block number from which to use an updated formula for calculating the number of faulty +nodes. This was introduced to enable existing network the ability to upgrade at a point in the future of the network, as +it is incompatible with the existing formula. For new networks, it is recommended to set this value to `0` to use the +updated formula immediately. + +To update this value, the same process can be followed as other hard-forks. \ No newline at end of file diff --git a/docs/Consensus/istanbul-rpc-api.md b/docs/Consensus/ibft/istanbul-rpc-api.md similarity index 58% rename from docs/Consensus/istanbul-rpc-api.md rename to docs/Consensus/ibft/istanbul-rpc-api.md index 8e8168f658..6775adf6f8 100644 --- a/docs/Consensus/istanbul-rpc-api.md +++ b/docs/Consensus/ibft/istanbul-rpc-api.md @@ -84,3 +84,48 @@ istanbul.propose(address, auth) #### Parameters `String` - The address of candidate `bool` - `true` votes in and `false` votes out + +### istanbul.nodeAddress +Retrieves the public address that is used to sign proposals, which is derived from the nodes `nodekey`. +``` +istanbul.nodeAddress() +``` + +#### Returns +`string` - The nodes public signing address + +### istanbul.getSignersFromBlock +Retrieves the public addresses for whose seals are included in the block. This means that they participated in the +consensus for this block and attested to its validity. +A block number may be optionally given, or else the current block is assumed. +``` +istanbul.getSignersFromBlock(blockNumber) +``` + +#### Parameters +`Number` - The block number to retrieve + +#### Returns +`Object` - + - `number`: `Number` - The retrieved block's number + - `hash`: `String` - The retrieved block's hash + - `author`: `String` - The address of the block proposer + - `committers`: `[]String` - The list of all addresses whose seal appears in this block + +### istanbul.getSignersFromBlockByHash +Retrieves the public addresses for whose seals are included in the block. This means that they participated in the +consensus for this block and attested to its validity. A block hash must be given, and does NOT default to the current +latest block. +``` +istanbul.getSignersFromBlockByHash(blockHash) +``` + +#### Parameters +`String` - The hash of the block to retrieve + +#### Returns +`Object` - + - `number`: `Number` - The retrieved block's number + - `hash`: `String` - The retrieved block's hash + - `author`: `String` - The address of the block proposer + - `committers`: `[]String` - The list of all addresses whose seal appears in this block \ No newline at end of file diff --git a/docs/Consensus/raft.md b/docs/Consensus/raft.md index 9161242603..2c4960a0ff 100644 --- a/docs/Consensus/raft.md +++ b/docs/Consensus/raft.md @@ -2,19 +2,44 @@ ## Introduction -The link attached holds an implementation of a [Raft](https://raft.github.io)-based consensus mechanism (using [etcd](https://github.com/coreos/etcd)'s [Raft implementation](https://github.com/coreos/etcd/tree/master/raft)) as an alternative to Ethereum's default proof-of-work. This is useful for closed-membership/consortium settings where byzantine fault tolerance is not a requirement, and there is a desire for faster blocktimes (on the order of milliseconds instead of seconds) and transaction finality (the absence of forking.) Also, compared with QuorumChain, this consensus mechanism does not "unnecessarily" create empty blocks, and effectively creates blocks "on-demand." +Quorum includes an implementation of a [Raft](https://raft.github.io)-based consensus mechanism (using [etcd](https://github.com/coreos/etcd)'s [Raft implementation](https://github.com/coreos/etcd/tree/master/raft)) as an alternative to Ethereum's default proof-of-work. This is useful for closed-membership/consortium settings where byzantine fault tolerance is not a requirement, and there is a desire for faster blocktimes (on the order of milliseconds instead of seconds) and transaction finality (the absence of forking.) This consensus mechanism does not "unnecessarily" create empty blocks, and effectively creates blocks "on-demand." When the `geth` binary is passed the `--raft` flag, the node will operate in "raft mode." ## Some implementation basics -Note: Though we use the etcd implementation of the Raft protocol, we speak of "Raft" more broadly to refer to the Raft protocol, and its use to achieve consensus for Quorum/Ethereum. +!!! note + Though we use the etcd implementation of the Raft protocol, we speak of "Raft" more broadly to refer to the Raft protocol, and its use to achieve consensus for Quorum/Ethereum. Both Raft and Ethereum have their own notion of a "node": -In Raft, a node in normal operation is either a "leader" or a "follower." There is a single leader for the entire cluster, which all log entries must flow through. There's also the concept of a "candidate", but only during leader election. We won't go into more detail about Raft here, because by design these details are opaque to applications built on it. +In Raft, a node in normal operation can be a "leader", "follower" or "learner." There is a single leader for the entire cluster, through which all log entries must flow through. There's also the concept of a "candidate", but only during leader election. We won't go into more detail about Raft here, because by design these details are opaque to applications built on it. A Raft network can be started with a set of verifiers and one of them would get elected as a leader when the network starts. If the leader node dies, re-election is triggered and new leader is elected by the network. Once the network is up additional verifier nodes(peers) or learner nodes can be added to this network. Brief summary of each type of nodes is given below: -In vanilla Ethereum, there is no such thing as a "leader" or "follower." It's possible for any node in the network to mine a new block -- which is akin to being the leader for that round. +### Leader +- mints blocks and sends the blocks to the verifier and learner nodes +- takes part in voting during re-election and can become verifier if it does not win majority of votes +- the network triggers re-election if the leader node dies. +- can add/remove learner/verifier and promote learner to verifier + +### Verifier +- follows the leader +- applies the blocks minted by the leader +- takes part in voting during re-election and can become leader if it wins majority of votes +- sends confirmation to leader +- can add/remove learner/verifier and promote learner to verifier + +### Learner +- follows the leader +- applies the blocks minted by the leader +- cannot take part in voting during re-election +- cannot become a verifier on its own +- it needs to be promoted to be a verifier by a leader or verifier +- it cannot add learner/verifier or promote learner to verifier +- it cannot remove other learner/verifier but it can remove itself + +It should be noted that when a node is added/removed as a verifier (peer), it impacts the Raft Quorum. However adding a node as learner does not change the Raft Quroum. Hence its recommended that when a new node is added to a long running network, the node is first added as a learner. Once the learner node syncs fully with the network, it can then be promoted to become a verifier. + +In vanilla Ethereum, there is no such thing as a "leader", "learner" or "follower." It's possible for any node in the network to mine a new block -- which is akin to being the leader for that round. In Raft-based consensus, we impose a one-to-one correspondence between Raft and Ethereum nodes: each Ethereum node is also a Raft node, and by convention, the leader of the Raft cluster is the only Ethereum node that should mine (or "mint") new blocks. A minter is responsible for bundling transactions into a block just like an Ethereum miner, but does not present a proof of work. @@ -23,9 +48,11 @@ Ethereum | Raft minter | leader verifier | follower +A learner node is passive node that just syncs blocks and can initiate transactions. + The main reasons we co-locate the leader and minter are (1) convenience, in that Raft ensures there is only one leader at a time, and (2) to avoid a network hop from a node minting blocks to the leader, through which all Raft writes must flow. Our implementation watches Raft leadership changes -- if a node becomes a leader it will start minting, and if a node loses its leadership, it will stop minting. -An observant reader might note that during raft leadership transitions, there could be a small period of time where more than one node might assume that it has minting duties; we detail how correctness is preserved in more detail later in this document. +An observant reader might note that during raft leadership transitions, there could be a small period of time where more than one node might assume that it has minting duties; we detail how correctness is preserved in the [Chain extension, races, and correctness](#chain-extension-races-and-correctness) section. We use the existing Ethereum p2p transport layer to communicate transactions between nodes, but we communicate blocks only through the Raft transport layer. They are created by the minter and flow from there to the rest of the cluster, always in the same order, via Raft. @@ -33,11 +60,12 @@ When the minter creates a block, unlike in vanilla Ethereum where the block is w From the point of view of Ethereum, Raft is integrated via an implementation of the [`Service`](https://godoc.org/github.com/jpmorganchase/quorum/node#Service) interface in [`node/service.go`](https://github.com/jpmorganchase/quorum/blob/master/node/service.go): "an individual protocol that can be registered into a node". Other examples of services are [`Ethereum`](https://godoc.org/github.com/jpmorganchase/quorum/eth#Ethereum) and [`Whisper`](https://godoc.org/github.com/jpmorganchase/quorum/whisper/whisperv5#Whisper). + ## The lifecycle of a transaction Let's follow the lifecycle of a typical transaction: -#### on any node (whether minter or verifier): +#### on any node (whether minter, verifier or learner): 1. The transaction is submitted via an RPC call to geth. 2. Using the existing (p2p) transaction propagation mechanism in Ethereum, the transaction is announced to all peers and, because our cluster is currently configured to use "static nodes," every transaction is sent to all peers in the cluster. @@ -45,7 +73,7 @@ Let's follow the lifecycle of a typical transaction: #### on the minter: 3. It reaches the minter, where it's included in the next block (see `mintNewBlock`) via the transaction pool. -4. Block creation triggers a [`NewMinedBlockEvent`](https://godoc.org/github.com/jpmorganchase/quorum/core#NewMinedBlockEvent), which the Raft protocol manager receives via its subscription `minedBlockSub`. The `minedBroadcastLoop` (in raft/handler.go) puts this new block to the `ProtocolManager.blockProposalC` channel. +4. Block creation triggers a [`NewMinedBlockEvent`](https://godoc.org/github.com/jpmorganchase/quorum/core#NewMinedBlockEvent), which the Raft protocol manager receives via its subscription `minedBlockSub`. The `minedBroadcastLoop` (in `raft/handler.go`) puts this new block to the `ProtocolManager.blockProposalC` channel. 5. `serveLocalProposals` is waiting at the other end of the channel. Its job is to RLP-encode blocks and propose them to Raft. Once it flows through Raft, this block will likely become the new head of the blockchain (on all nodes.) #### on every node: @@ -57,9 +85,9 @@ Let's follow the lifecycle of a typical transaction: 8. The block is now handled by `applyNewChainHead`. This method checks whether the block extends the chain (i.e. it's parent is the current head of the chain; see below). If it does not extend the chain, it is simply ignored as a no-op. If it does extend chain, the block is validated and then written as the new head of the chain by [`InsertChain`](https://godoc.org/github.com/jpmorganchase/quorum/core#BlockChain.InsertChain). 9. A [`ChainHeadEvent`](https://godoc.org/github.com/jpmorganchase/quorum/core#ChainHeadEvent) is posted to notify listeners that a new block has been accepted. This is relevant to us because: -* It removes the relevant transaction from the transaction pool. -* It removes the relevant transaction from `speculativeChain`'s `proposedTxes` (see below). -* It triggers `requestMinting` in (minter.go), telling the node to schedule the minting of a new block if any more transactions are pending. + * It removes the relevant transaction from the transaction pool. + * It removes the relevant transaction from `speculativeChain`'s `proposedTxes` (see below). + * It triggers `requestMinting` in (`minter.go`), telling the node to schedule the minting of a new block if any more transactions are pending. The transaction is now available on all nodes in the cluster with complete finality. Because Raft guarantees a single ordering of entries stored in its log, and because everything that is committed is guaranteed to remain so, there is no forking of the blockchain built upon Raft. @@ -118,13 +146,13 @@ This default of 50ms is configurable via the `--raftblocktime` flag to geth. One of the ways our approach differs from vanilla Ethereum is that we introduce a new concept of "speculative minting." This is not strictly required for the core functionality of Raft-based Ethereum consensus, but rather it is an optimization that affords lower latency between blocks (or: faster transaction "finality.") -It takes some time for a block to flow through Raft (consensus) to become the head of the chain. If we synchronously waited for a block to become the new head of the chain before creating the new block, any transactions that we receive would take more time to make it into the chain. +It takes some time for a block to flow through Raft (consensus) and become the head of the chain. If we synchronously waited for a block to become the new head of the chain before creating the new block, any transactions that we receive would take more time to make it into the chain. In speculative minting we allow the creation of a new block (and its proposal to Raft) before its parent has made it all the way through Raft and into the blockchain. Since this can happen repeatedly, these blocks (which each have a reference to their parent block) can form a sort of chain. We call this a "speculative chain." -During the course of operation that a speculative chain forms, we keep track of the subset of transactions in the pool that we have already put into blocks (in the speculative chain) that have not yet made it into the blockchain (and whereupon a [`core.ChainHeadEvent`](https://godoc.org/github.com/jpmorganchase/quorum/core#ChainHeadEvent) occurs.) These are called "proposed transactions" (see speculative_chain.go). +During the course of operation that a speculative chain forms, we keep track of the subset of transactions in the pool that we have already put into blocks (in the speculative chain) that have not yet made it into the blockchain (and whereupon a [`core.ChainHeadEvent`](https://godoc.org/github.com/jpmorganchase/quorum/core#ChainHeadEvent) occurs.) These are called "proposed transactions" (see `speculative_chain.go`). Per the presence of "races" (as we detail above), it is possible that a block somewhere in the middle of a speculative chain ends up not making into the chain. In this scenario an [`InvalidRaftOrdering`](https://godoc.org/github.com/jpmorganchase/quorum/raft#InvalidRaftOrdering) event will occur, and we clean up the state of the speculative chain accordingly. @@ -135,14 +163,14 @@ There is currently no limit to the length of these speculative chains, but we pl * `head`: The last-created speculative block. This can be `nil` if the last-created block is already included in the blockchain. * `proposedTxes`: The set of transactions which have been proposed to Raft in some block, but not yet included in the blockchain. * `unappliedBlocks`: A queue of blocks which have been proposed to Raft but not yet committed to the blockchain. - - When minting a new block, we enqueue it at the end of this queue - - `accept` is called to remove the oldest speculative block when it's accepted into the blockchain. - - When an [`InvalidRaftOrdering`](https://godoc.org/github.com/jpmorganchase/quorum/raft#InvalidRaftOrdering) occurs, we unwind the queue by popping the most recent blocks from the "new end" of the queue until we find the invalid block. We must repeatedly remove these "newer" speculative blocks because they are all dependent on a block that we know has not been included in the blockchain. + - When minting a new block, we enqueue it at the end of this queue + - `accept` is called to remove the oldest speculative block when it's accepted into the blockchain. + - When an [`InvalidRaftOrdering`](https://godoc.org/github.com/jpmorganchase/quorum/raft#InvalidRaftOrdering) occurs, we unwind the queue by popping the most recent blocks from the "new end" of the queue until we find the invalid block. We must repeatedly remove these "newer" speculative blocks because they are all dependent on a block that we know has not been included in the blockchain. * `expectedInvalidBlockHashes`: The set of blocks which build on an invalid block, but haven't passsed through Raft yet. We remove these as we get them back. When these non-extending blocks come back through Raft we remove them from the speculative chain. We use this set as a "guard" against trying to trim the speculative chain when we shouldn't. ## The Raft transport layer -We communicate blocks over the HTTP transport layer built in to etcd Raft. It's also (at least theoretically) possible to use p2p protocol built-in to Ethereum as a transport for Raft. In our testing we found the default etcd HTTP transport to be more reliable than the p2p (at least as implemented in geth) under high load. +We communicate blocks over the HTTP transport layer built in to etcd Raft. It's also (at least theoretically) possible to use the p2p protocol built-in to Ethereum as a transport for Raft. In our testing we found the default etcd HTTP transport to be more reliable than the p2p (at least as implemented in geth) under high load. Quorum listens on port 50400 by default for the raft transport, but this is configurable with the `--raftport` flag. @@ -154,31 +182,12 @@ Currently Raft-based consensus requires that all _initial_ nodes in the cluster To remove a node from the cluster, attach to a JS console and issue `raft.removePeer(raftId)`, where `raftId` is the number of the node you wish to remove. For initial nodes in the cluster, this number is the 1-indexed position of the node's enode ID in the static peers list. Once a node has been removed from the cluster, it is permanent; this raft ID can not ever re-connect to the cluster in the future, and the party must re-join the cluster with a new raft ID. -To add a node to the cluster, attach to a JS console and issue `raft.addPeer(enodeId)`. Note that like the enode IDs listed in the static peers JSON file, this enode ID should include a `raftport` querystring parameter. This call will allocate and return a raft ID that was not already in use. After `addPeer`, start the new geth node with the flag `--raftjoinexisting RAFTID` in addition to `--raft`. - -## FAQ - -**Could you have a single- or two-node cluster? More generally, could you have an even number of nodes ?** +* To add a verifier node to the cluster, attach to a JS console and issue `raft.addPeer(enodeId)` +* To add a learner node to the cluster, attach to a JS console and issue `raft.addLearner(enodeId)` +* To promote a learner to become verifier in the cluster, attach to a JS console of leader/verifier node and issue `raft.promoteToPeer(raftId)`. -A cluster can tolerate failures that leave a quorum (majority) available. So a cluster of two nodes can't tolerate any failures, three nodes can tolerate one, and five nodes can tolerate two. Typically Raft clusters have an odd number of nodes, since an even number provides no failure tolerance benefit. +Note that like the enode IDs listed in the static peers JSON file, this enode ID should include a `raftport` querystring parameter. This call will allocate and return a raft ID that was not already in use. After `addPeer`, start the new geth node with the flag `--raftjoinexisting RAFTID` in addition to `--raft`. -**What happens if you don't assume minter and leader are the same node?** - -There's no hard reason they couldn't be different. We just co-locate the minter and leader as an optimization. - -* It saves one network call communicating the block to the leader. -* It provides a simple way to choose a minter. If we didn't use the Raft leader we'd have to build in "minter election" at a higher level. - -Additionally there could even be multiple minters running at the same time, but this would produce contention for which blocks actually extend the chain, reducing the productivity of the cluster (see "races" above). - -**I thought there were no forks in a Raft-based blockchain. What's the deal with "speculative minting"?** - -"Speculative chains" are not forks in the blockchain. They represent a series ("chain") of blocks that have been sent through Raft, after which each of the blocks may or may not actually end up being included in *the blockchain*. - -**Can transactions be reversed? Since raft log entries can be disregarded as "no-ops", does this imply transaction reversal?** - -No. When a Raft log entry containing a new block is disregarded as a "no-op", its transactions will remain in the transaction pool, and so they will be included in a future block in the chain. - -**What's the deal with the block timestamp being stored in nanoseconds (instead of seconds, like other consensus mechanisms)?** +## FAQ -With raft-based consensus we can produce far more than one block per second, which vanilla Ethereum implicitly disallows (as the default timestamp resolution is in seconds and every block must have a timestamp greater than its parent). For Raft, we store the timestamp in nanoseconds and ensure it is incremented by at least 1 nanosecond per block. +Answers to frequently asked questions can be found on the main [Quorum FAQ page](../FAQ.md). diff --git a/docs/FAQ.md b/docs/FAQ.md index c3157a17f1..ce4489cfab 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,5 +1,9 @@ -??? question "I've ran into an issue with Quorum, where do I get support?" - There are two places Quorum engineering team monitors on an on-going basis: issues in this and related repositories and on Quorum Slack. Quorum Slack is the best place to query the community and get immediate help. Auto-inviter is available [here](https://clh7rniov2.execute-api.us-east-1.amazonaws.com/Express/). +### Quorum FAQ + +??? question "I've run into an issue with Quorum, where do I get support?" + The [Quorum Slack channels](https://clh7rniov2.execute-api.us-east-1.amazonaws.com/Express/) are the best place to query the community and get immediate help. + + The Quorum engineering team monitors Slack as well as any issues raised on the Quorum GitHub repositories (e.g. [Quorum](https://github.com/jpmorganchase/quorum/), [Tessera](https://github.com/jpmorganchase/tessera), [Quorum-Examples](https://github.com/jpmorganchase/quorum-examples), etc.). ??? question "How does Quorum achieve Transaction Privacy?" Quorum achieves Transaction Privacy by: @@ -23,11 +27,8 @@ ??? question "Should I include originating node in private transaction?" No, you should not. In Quorum, including originating node's `privateFor` will result in an error. If you would like to create a private contract that is visible to the originating node only please use this format: `privateFor: []` per https://github.com/jpmorganchase/quorum/pull/165 -??? question "Is it possible to run a Quorum node without Transaction Manager?" - It is possible to run a node without a corresponding Transaction Manager, to do this instead of a matching Tessera/Constellation node's socket configuration should be set to `PRIVATE_CONFIG=ignore ...`. The node running such configuration is not going to broadcast matching private keys (please ensure that there is no transaction manager running for it) and will be unable to participate in any private transactions. - -??? info "Known Raft consensus node misconfiguration" - Please see https://github.com/jpmorganchase/quorum/issues/410 +??? question "Is it possible to run a Quorum node without a Transaction Manager?" + Starting a Quorum node with `PRIVATE_CONFIG=ignore` (instead of `PRIVATE_CONFIG=path/to/tm.ipc`) will start the node without a Transaction Manager. The node will not broadcast matching private keys (please ensure that there is no transaction manager running for it) and will be unable to participate in any private transactions. ??? question "Is there an official docker image for Quorum/Constellation/Tessera?" Yes! The [official docker containers](https://hub.docker.com/u/quorumengineering/): @@ -36,5 +37,44 @@ `quorumengineering/constellation:latest` `quorumengineering/tessera:latest` -??? question "Can I mix Quorum nodes with different consensus configuration?" +??? question "Can I create a network of Quorum nodes using different consensus mechanisms?" Unfortunately, that is not possible. Quorum nodes configured with raft will only be able to work correctly with other nodes running raft consensus. This applies to all other supported consensus algorithms. + +??? info "Quorum version compatibility table" + | | Adding new node v2.0.x | Adding new node v2.1.x | Adding new node v2.2.x | + | ----------------------------------- | ---------------------- | ---------------------- | ---------------------- | + | Existing chain consisting of v2.0.x | block sync
public txn
private txn
| block sync | block sync | + | Existing chain consisting of v2.1.x | block sync | block sync
public txn
private txn
| block sync
public txn
private txn
| + | Existing chain consisting of v2.2.x | block sync | block sync
public txn
private txn
| block sync
public txn
private txn
| + + **Note:** While every Quorum v2 client will be able to connect to any other v2 client, the usefullness will be severely degraded. Red color signifies that while connectivity is possible, red colored versions will be unable to send public or private txns to the rest of the net due to the EIP155 changes in the signer implemented in newer versions. + +### Raft FAQ + +??? question "Could you have a single- or two-node cluster? More generally, could you have an even number of nodes?" + A cluster can tolerate failures that leave a quorum (majority) available. So a cluster of two nodes can't tolerate any failures, three nodes can tolerate one, and five nodes can tolerate two. Typically Raft clusters have an odd number of nodes, since an even number provides no failure tolerance benefit. + +??? question "What happens if you don't assume minter and leader are the same node?" + There's no hard reason they couldn't be different. We just co-locate the minter and leader as an optimization. + + * It saves one network call communicating the block to the leader. + * It provides a simple way to choose a minter. If we didn't use the Raft leader we'd have to build in "minter election" at a higher level. + + Additionally there could even be multiple minters running at the same time, but this would produce contention for which blocks actually extend the chain, reducing the productivity of the cluster (see [Raft: Chain extension, races, and correctness](../Consensus/raft/#chain-extension-races-and-correctness) above). + +??? question "I thought there were no forks in a Raft-based blockchain. What's the deal with "speculative minting"?" + "Speculative chains" are not forks in the blockchain. They represent a series ("chain") of blocks that have been sent through Raft, after which each of the blocks may or may not actually end up being included in *the blockchain*. + +??? question "Can transactions be reversed? Since raft log entries can be disregarded as "no-ops", does this imply transaction reversal?" + No. When a Raft log entry containing a new block is disregarded as a "no-op", its transactions will remain in the transaction pool, and so they will be included in a future block in the chain. + +??? question "What's the deal with the block timestamp being stored in nanoseconds (instead of seconds, like other consensus mechanisms)?" + With raft-based consensus we can produce far more than one block per second, which vanilla Ethereum implicitly disallows (as the default timestamp resolution is in seconds and every block must have a timestamp greater than its parent). For Raft, we store the timestamp in nanoseconds and ensure it is incremented by at least 1 nanosecond per block. + +??? question "Why do I see "Error: Number can only safely store up to 53 bits" when using web3js with Raft?" + As mentioned above, Raft stores the timestamp in nanoseconds, so it is too large to be held as a number in javascript. + You need to modify your code to take account of this. An example can be seen [here](https://github.com/jpmorganchase/quorum.js/blob/master/lib/index.js#L35). + A future quorum release will address this issue. + +??? info "Known Raft consensus node misconfiguration" + Please see https://github.com/jpmorganchase/quorum/issues/410 diff --git a/docs/Features/dns.md b/docs/Features/dns.md new file mode 100644 index 0000000000..2d5642c769 --- /dev/null +++ b/docs/Features/dns.md @@ -0,0 +1,31 @@ +# DNS for Quorum + +DNS support in Quorum has two distinct areas, usage in the static nodes file and usage in the +node discovery protocol. You are free to use one and not the other, or to mix them as the use case +requires. + +## Static nodes + +Static nodes are nodes we keep reference to even if the node is not alive, so that is the nodes comes alive, +then we can connect to it. Hostnames are permitted here, and are resolved once at startup. If a static peer goes offline +and its IP address changes, then it is expected that that peer would re-establish the connection in a fully static +network, or have discovery enabled. + +## Discovery + +DNS is not supported for the discovery protocol. Use a bootnode instead, which can use a DNS name that is repeatedly +resolved. + +## Compatibility +For Raft, the whole network must be on version 2.4.0 of Quorum for DNS to function properly. DNS must +be explicitly enabled using the `--raftdnsenable` flag for each node once the node has migrated to version 2.4.0 of Quorum +The network runs fine when some nodes are in 2.4.0 version and some in older version as long as this feature is not enabled. For safe migration the recommended approach is as below: +* migrate the nodes to `geth` 2.4.0 version without using `--raftdnsenable` flag +* once the network is fully migrated, restart the nodes with `--raftdnsenable` to enable the feature + +Please note that in a partially migrated network (where some nodes are on version 2.4.0 and others on lower version) **with DNS feature enabled** for migrated nodes, `raft.addPeer` should not be invoked with Hostname till entire network migrates to 2.4.0 version. If invoked, this call will crash all nodes running in older version and these nodes will have to restarted with `geth` of version 2.4.0 of Quorum. `raft.addPeer` can still be invoked with IP address and network will work fine. + +### Note +In a network where all nodes are running on Quorum version 2.4.0, with few nodes enabled for DNS, we recommend the + `--verbosity` to be 3 or below. We have observed that nodes which are not enabled for DNS fail to restart if + `raft.addPeer` is invoked with host name if `--verbosity` is set above 3. \ No newline at end of file diff --git a/docs/Getting Started/7Nodes.md b/docs/Getting Started/7Nodes.md deleted file mode 100644 index 30d221314a..0000000000 --- a/docs/Getting Started/7Nodes.md +++ /dev/null @@ -1,222 +0,0 @@ -# 7nodes -## Demonstrating Privacy -The [7nodes example](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) comes with some simple contracts to demonstrate the privacy features of Quorum. - -In this demo we will: - -* Send a private transaction between nodes 1 and 7 -* Show that only nodes 1 and 7 are able to view the initial state of the contract -* Have Node 1 update the state of the contract and, once the block containing the updated transaction is validated by the network, again verify that only nodes 1 and 7 are able to see the updated state of the contract - -!!! tip - [Constellation](../../Privacy/Constellation/Constellation) or [Tessera](../../Privacy/Tessera/Tessera) is used to enable the privacy features of Quorum. To start a Quorum node without its associated privacy transaction manager, set `PRIVATE_CONFIG=ignore` when starting the node. - -### Sending a private transaction - -First start running the 7nodes example by following the instructions in the [quorum-examples](../Quorum-Examples#getting-started), then send an example private contract from Node 1 to Node 7 (this is denoted by the public key passed via `privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]` in `private-contract.js`): -``` bash -./runscript.sh private-contract.js -``` -Make note of the `TransactionHash` printed to the terminal. - -### Inspecting the Quorum nodes - -We can inspect any of the Quorum nodes by using `geth attach` to open the Geth JavaScript console. For this demo, we will be inspecting Node 1, Node 7 and Node 4. - -It is recommended to use separate terminal windows for each node we are inspecting. In each terminal, ensure you are in the `path/to/7nodes` directory, then: - -- If you aren't already running the 7nodes example, in terminal 1 run `./{consensus}-init.sh` followed by `./{consensus}-start.sh` -- In terminal 1 run `geth attach ipc:qdata/dd1/geth.ipc` to attach to node 1 -- In terminal 2 run `geth attach ipc:qdata/dd4/geth.ipc` to attach to node 4 -- In terminal 3 run `geth attach ipc:qdata/dd7/geth.ipc` to attach to node 7 - -To look at the private transaction that was just sent, run the following command in one of the terminals: -``` sh -eth.getTransaction("0xe28912c5694a1b8c4944b2252d5af21724e9f9095daab47bac37b1db0340e0bf") -``` -where you should replace this hash with the TransactionHash that was previously printed to the terminal. This will print something of the form: -``` sh -{ - blockHash: "0x4d6eb0d0f971b5e0394a49e36ba660c69e62a588323a873bb38610f7b9690b34", - blockNumber: 1, - from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", - gas: 4700000, - gasPrice: 0, - hash: "0xe28912c5694a1b8c4944b2252d5af21724e9f9095daab47bac37b1db0340e0bf", - input: "0x58c0c680ee0b55673e3127eb26e5e537c973cd97c70ec224ccca586cc4d31ae042d2c55704b881d26ca013f15ade30df2dd196da44368b4a7abfec4a2022ec6f", - nonce: 0, - r: "0x4952fd6cd1350c283e9abea95a2377ce24a4540abbbf46b2d7a542be6ed7cce5", - s: "0x4596f7afe2bd23135fa373399790f2d981a9bb8b06144c91f339be1c31ec5aeb", - to: null, - transactionIndex: 0, - v: "0x25", - value: 0 -} -``` - -Note the `v` field value of `"0x25"` or `"0x26"` (37 or 38 in decimal) which indicates this transaction has a private payload (input). - - -#### Checking the state of the contract -For each of the 3 nodes we'll use the Geth JavaScript console to create a variable called `address` which we will assign to the address of the contract created by Node 1. The contract address can be found in two ways: - -- In Node 1's log file: `7nodes/qdata/logs/1.log` -- By reading the `contractAddress` param after calling `eth.getTransactionReceipt(txHash)` ([Ethereum API documentation](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethgettransactionreceipt)) where `txHash` is the hash printed to the terminal after sending the transaction. - -Once you've identified the contract address, run the following command in each terminal: -``` javascript -> var address = "0x1932c48b2bf8102ba33b4a6b545c32236e342f34"; //replace with your contract address -``` - -Next we'll use ```eth.contract``` to define a contract class with the simpleStorage ABI definition in each terminal: -``` javascript -> var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"type":"constructor"}]; -> var private = eth.contract(abi).at(address) -``` - -The function calls are now available on the contract instance and you can call those methods on the contract. Let's start by examining the initial value of the contract to make sure that only nodes 1 and 7 can see the initialized value. -- In terminal window 1 (Node 1): -``` javascript -> private.get() -42 -``` -- In terminal window 2 (Node 4): -``` javascript -> private.get() -0 -``` -- In terminal window 3 (Node 7): -``` javascript -> private.get() -42 -``` - -So we can see nodes 1 and 7 are able to read the state of the private contract and its initial value is 42. If you look in `private-contract.js` you will see that this was the value set when the contract was created. Node 4 is unable to read the state. - -### Updating the state of the contract - -Next we'll have Node 1 set the state to the value `4` and verify only nodes 1 and 7 are able to view the new state. - -In terminal window 1 (Node 1): -``` javascript -> private.set(4,{from:eth.coinbase,privateFor:["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]}); -"0xacf293b491cccd1b99d0cfb08464a68791cc7b5bc14a9b6e4ff44b46889a8f70" -``` -You can check the log files in `7nodes/qdata/logs/` to see each node validating the block with this new private transaction. Once the block containing the transaction has been validated we can once again check the state from each node 1, 4, and 7. -- In terminal window 1 (Node 1): -``` javascript -> private.get() -4 -``` -- In terminal window 2 (Node 4): -``` javascript -> private.get() -0 -``` -- In terminal window 3 (Node 7): -``` javascript -> private.get() -4 -``` -And there you have it. All 7 nodes are validating the same blockchain of transactions, the private transactions carrying only a 512 bit hash, and only the parties to private transactions are able to view and update the state of private contracts. - -## Permissions - -Node Permissioning is a feature in Quorum that allows only a pre-defined set of nodes (as identified by their remotekey/enodes) to connect to the permissioned network. - -In this demo we will: -- Set up a network with a combination of permissioned and non-permissioned nodes in the cluster -- Look at the details of the `permissioned-nodes.json` file -- Demonstrate that only the nodes that are specified in `permissioned-nodes.json` can connect to the network - -### Verify only permissioned nodes are connected to the network. - -Attach to the individual nodes via `geth attach path/to/geth.ipc` and use `admin.peers` to check the connected nodes: - -``` sh -❯ geth attach qdata/dd1/geth.ipc -Welcome to the Geth JavaScript console! - -instance: Geth/v1.7.2-stable/darwin-amd64/go1.9.2 -coinbase: 0xed9d02e382b34818e88b88a309c7fe71e65f419d -at block: 1 (Mon, 29 Oct 47909665359 22:09:51 EST) - datadir: /Users/joel/jpm/quorum-examples/examples/7nodes/qdata/dd1 - modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0 - -> admin.peers -[{ - caps: ["eth/63"], - id: "0ba6b9f606a43a95edc6247cdb1c1e105145817be7bcafd6b2c0ba15d58145f0dc1a194f70ba73cd6f4cdd6864edc7687f311254c7555cc32e4d45aeb1b80416", - name: "Geth/v1.7.2-stable/darwin-amd64/go1.9.2", - network: { - localAddress: "127.0.0.1:65188", - remoteAddress: "127.0.0.1:21001" - }, - protocols: { - eth: { - difficulty: 0, - head: "0xc23b4ebccc79e2636d66939924d46e618269ca1beac5cf1ec83cc862b88b1b71", - version: 63 - } - } -}, -... -] -``` - -You can also inspect the log files under `qdata/logs/*.log` for further diagnostics messages around incoming / outgoing connection requests. `grep` for `ALLOWED-BY` or `DENIED-BY`. Be sure to enable verbosity for p2p module. - -### Permissioning configuration - -Permissioning is granted based on the remote key of the geth node. The remote keys are specified in the `permissioned-nodes.json` and is placed under individual node's ``. - -The below sample `permissioned-nodes.json` provides a list of nodes permissioned to join the network (node ids truncated for clarity): - -``` json -[ - "enode://8475a01f22a1f48116dc1f0d22ecaaaf77e@127.0.0.1:30301", - "enode://b5660501f496e60e59ded734a889c97b7da@127.0.0.1:30302", - "enode://54bd7ff4bd971fb80493cf4706455395917@127.0.0.1:30303" -] -``` - -### Enabling/Disabling permissions - -An individual node can enable/disable permissioning by passing the `-permissioned` command line flag. If enabled, then only the nodes that are in the `/permissioned-nodes.json` can connect to it. Further, these are the only nodes that this node can make outbound connections to as well. - -``` -MISCELLANEOUS OPTIONS: ---permissioned If enabled, the node will allow only a defined list of nodes to connect -``` - -## Next steps -Additional samples can be found in `quorum-examples/examples/7nodes/samples` for you to use and edit. You can also create your own contracts to help you understand how the nodes in a Quorum network work together. - -## Reducing the number of nodes -It is easy to reduce the number of nodes used in the example. You may want to do this for memory usage reasons or just to experiment with a different network configuration. - -To run the example with 5 nodes instead of 7, the following changes need to be made: -1. In __`raft-start.sh`__: - - Comment out the following lines used to start Quorum nodes 6 & 7 - ```sh - # PRIVATE_CONFIG=qdata/c6/tm.ipc nohup geth --datadir qdata/dd6 $ARGS --raftport 50406 --rpcport 22005 --port 21005 --unlock 0 --password passwords.txt 2>>qdata/logs/6.log & - # PRIVATE_CONFIG=qdata/c7/tm.ipc nohup geth --datadir qdata/dd7 $ARGS --raftport 50407 --rpcport 22006 --port 21006 --unlock 0 --password passwords.txt 2>>qdata/logs/7.log & - ``` - -1. In __`constellation-start.sh`__ or __`tessera-start.sh`__ (depending on which privacy manager you are using): - - Change the 2 instances of `for i in {1..7}` to `for i in {1..5}` - -After making these changes, the `raft-init.sh` and `raft-start.sh` scripts can be run as normal. - -`private-contract.js` will also need to be updated as this is set up to send a transaction from node 1 to node 7. To update the private contract to instead send to node 5, the following steps need to be followed: - -1. Copy node 5's public key from `./keys/tm5.pub` - -2. Replace the existing `privateFor` in `private-contract.js` with the key copied from `tm5.pub` key, e.g.: - ``` javascript - var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["R56gy4dn24YOjwyesTczYa8m5xhP6hF2uTMCju/1xkY="]}, function(e, contract) {...} - ``` - -After saving this change, the `./runscript.sh private-contract.js` command can be run as usual to submit the private contract. You can then follow steps described above to verify that node 5 can see the transaction payload and that nodes 2-4 are unable to see the payload. diff --git a/docs/Getting Started/Creating-A-Network-From-Scratch.md b/docs/Getting Started/Creating-A-Network-From-Scratch.md new file mode 100644 index 0000000000..e8675f0c5f --- /dev/null +++ b/docs/Getting Started/Creating-A-Network-From-Scratch.md @@ -0,0 +1,1171 @@ +# Creating a network from scratch + +This section details easy to follow step by step instructions of how to setup one or more Quorum nodes from scratch for all new starters. + +Let's go through step by step instructions to setup a Quorum node with Raft consensus. + +## Quorum with Raft consensus +1. On each machine build Quorum as described in the [Installing](../Installing) section. Ensure that PATH contains geth and bootnode + ``` + $ git clone https://github.com/jpmorganchase/quorum.git + $ cd quorum + $ make all + $ export PATH=$(pwd)/build/bin:$PATH + ``` + +2. Create a working directory which will be the base for the new node(s) and change into it + ``` + $ mkdir fromscratch + $ cd fromscratch + $ mkdir new-node-1 + ``` +3. Generate one or more accounts for this node and take down the account address. A funded account may be required depending what you are trying to accomplish + ``` + $ geth --datadir new-node-1 account new + + INFO [06-07|14:52:18.742] Maximum peer count ETH=25 LES=0 total=25 + Your new account is locked with a password. Please give a password. Do not forget this password. + Passphrase: + Repeat passphrase: + Address: {679fed8f4f3ea421689136b25073c6da7973418f} + + Please note the keystore file generated inside new-node-1 includes the address in the last part of its filename. + + $ ls new-node-1/keystore + UTC--2019-06-17T09-29-06.665107000Z--679fed8f4f3ea421689136b25073c6da7973418f + ``` + + !!! note + You could generate multiple accounts for a single node, or any number of accounts for additional nodes and pre-allocate them with funds in the genesis.json file (see below) + +4. Create a `genesis.json` file see example [here](../genesis). The `alloc` field should be pre-populated with the account you generated at previous step + ``` + $ vim genesis.json + ... alloc holds 'optional' accounts with a pre-funded amounts. In this example we are funding the accounts 679fed8f4f3ea421689136b25073c6da7973418f (generated from the step above) and c5c7b431e1629fb992eb18a79559f667228cd055. + { + "alloc": { + "0x679fed8f4f3ea421689136b25073c6da7973418f": { + "balance": "1000000000000000000000000000" + }, + "0xc5c7b431e1629fb992eb18a79559f667228cd055": { + "balance": "2000000000000000000000000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "config": { + "homesteadBlock": 0, + "byzantiumBlock": 0, + "chainId": 10, + "eip150Block": 0, + "eip155Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip158Block": 0, + "isQuorum": true + }, + "difficulty": "0x0", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0xE0000000", + "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", + "nonce": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x00" + } + ``` +5. Generate node key and copy it into datadir + ``` + $ bootnode --genkey=nodekey + $ cp nodekey new-node-1/ + ``` +6. Execute below command to display enode id of the new node + ``` + $ bootnode --nodekey=new-node-1/nodekey --writeaddress > new-node-1/enode + $ cat new-node-1/enode + '70399c3d1654c959a02b73acbdd4770109e39573a27a9b52bd391e5f79b91a42d8f2b9e982959402a97d2cbcb5656d778ba8661ec97909abc72e7bb04392ebd8' + ``` +7. Create a file called `static-nodes.json` and edit it to match this [example](../permissioned-nodes). Your file should contain a single line for your node with your enode's id and the ports you are going to use for devp2p and raft. Ensure that this file is in your nodes data directory + ``` + $ vim static-nodes.json + .... paste below lines with enode generated in previous step, port 21000;IP 127.0.0.1 and raft port set as 50000 + [ + "enode://70399c3d1654c959a02b73acbdd4770109e39573a27a9b52bd391e5f79b91a42d8f2b9e982959402a97d2cbcb5656d778ba8661ec97909abc72e7bb04392ebd8@127.0.0.1:21000?discport=0&raftport=50000" + ] + $ cp static-nodes.json new-node-1 + ``` +8. Initialize new node with below command. + ``` + $ geth --datadir new-node-1 init genesis.json + + INFO [06-07|15:45:17.508] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-07|15:45:17.516] Allocated cache and file handles database=/Users/krish/new-node-1/geth/chaindata cache=16 handles=16 + INFO [06-07|15:45:17.524] Writing custom genesis block + INFO [06-07|15:45:17.524] Persisted trie from memory database nodes=1 size=152.00B time=75.344µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-07|15:45:17.525] Successfully wrote genesis state database=chaindata hash=ec0542…9665bf + INFO [06-07|15:45:17.525] Allocated cache and file handles database=/Users/krish/new-node-1/geth/lightchaindata cache=16 handles=16 + INFO [06-07|15:45:17.527] Writing custom genesis block + INFO [06-07|15:45:17.527] Persisted trie from memory database nodes=1 size=152.00B time=60.76µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-07|15:45:17.527] Successfully wrote genesis state database=lightchaindata hash=ec0542…9665bf + ``` +9. Start your node by first creating a script as below and then starting it: + ``` + $ vim startnode1.sh + ... paste below commands. It will start it in the background. + #!/bin/bash + PRIVATE_CONFIG=ignore nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 >> node.log 2>&1 & + + $ chmod +x startnode1.sh + $ ./startnode1.sh + ``` + + !!! note + This configuration starts Quorum without privacy support as could be evidenced in prefix `PRIVATE_CONFIG=ignore`, please see below sections on [how to enable privacy with privacy transaction managers](#adding-privacy-transaction-manager). + + Your node is now operational and you may attach to it with below commands. + ``` + $ geth attach new-node-1/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xedf53f5bf40c99f48df184441137659aed899c48 + at block: 0 (Thu, 01 Jan 1970 01:00:00 BST) + datadir: /Users/krish/fromscratch/new-node-1 + modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > raft.cluster + [{ + ip: "127.0.0.1", + nodeId: "a5596803caebdc9c5326e1a0775563ad8e4aa14aa3530f0ae16d3fd8d7e48bc0b81342064e22094ab5d10303ab5721650af561f2bcdc54d705f8b6a8c07c94c3", + p2pPort: 21000, + raftId: 1, + raftPort: 50000 + }] + > raft.leader + "a5596803caebdc9c5326e1a0775563ad8e4aa14aa3530f0ae16d3fd8d7e48bc0b81342064e22094ab5d10303ab5721650af561f2bcdc54d705f8b6a8c07c94c3" + > raft.role + "minter" + > + > exit + ``` + +### Adding additional node +1. Complete steps 1, 2, 5, and 6 from the previous guide + + ``` + $ mkdir new-node-2 + $ bootnode --genkey=nodekey2 + $ cp nodekey2 new-node-2/nodekey + $ bootnode --nodekey=new-node-2/nodekey --writeaddress + 56e81550db3ccbfb5eb69c0cfe3f4a7135c931a1bae79ea69a1a1c6092cdcbea4c76a556c3af977756f95d8bf9d7b38ab50ae070da390d3abb3d7e773099c1a9 + ``` +2. Retrieve current chains `genesis.json` and `static-nodes.json`. `static-nodes.json` should be placed into new nodes data dir + ``` + $ cp static-nodes.json new-node-2 + ``` + +3. Edit `static-nodes.json` and add new entry for the new node you are configuring (should be last) + ``` + $ vim new-node-2/static-nodes.json + .... append new-node-2's enode generated in step 1, port 21001;IP 127.0.0.1 and raft port set as 50001 + + [ + "enode://70399c3d1654c959a02b73acbdd4770109e39573a27a9b52bd391e5f79b91a42d8f2b9e982959402a97d2cbcb5656d778ba8661ec97909abc72e7bb04392ebd8@127.0.0.1:21000?discport=0&raftport=50000", + "enode://56e81550db3ccbfb5eb69c0cfe3f4a7135c931a1bae79ea69a1a1c6092cdcbea4c76a556c3af977756f95d8bf9d7b38ab50ae070da390d3abb3d7e773099c1a9@127.0.0.1:21001?discport=0&raftport=50001" + ] + ``` + +4. Initialize new node as given below: + + ``` + $ geth --datadir new-node-2 init genesis.json + + INFO [06-07|16:34:39.805] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-07|16:34:39.814] Allocated cache and file handles database=/Users/krish/fromscratch/new-node-2/geth/chaindata cache=16 handles=16 + INFO [06-07|16:34:39.816] Writing custom genesis block + INFO [06-07|16:34:39.817] Persisted trie from memory database nodes=1 size=152.00B time=59.548µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-07|16:34:39.817] Successfully wrote genesis state database=chaindata hash=f02d0b…ed214a + INFO [06-07|16:34:39.817] Allocated cache and file handles database=/Users/krish/fromscratch/new-node-2/geth/lightchaindata cache=16 handles=16 + INFO [06-07|16:34:39.819] Writing custom genesis block + INFO [06-07|16:34:39.819] Persisted trie from memory database nodes=1 size=152.00B time=43.733µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-07|16:34:39.819] Successfully wrote genesis state database=lightchaindata hash=f02d0b…ed214a + ``` + +5. Connect to an already running node of the chain and execute raft `addPeer` command. + ``` + $ geth attach new-node-1/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xedf53f5bf40c99f48df184441137659aed899c48 + at block: 0 (Thu, 01 Jan 1970 01:00:00 BST) + datadir: /Users/krish/fromscratch/new-node-1 + modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > raft.addPeer('enode://56e81550db3ccbfb5eb69c0cfe3f4a7135c931a1bae79ea69a1a1c6092cdcbea4c76a556c3af977756f95d8bf9d7b38ab50ae070da390d3abb3d7e773099c1a9@127.0.0.1:21001?discport=0&raftport=50001') + 2 + > raft.cluster + [{ + ip: "127.0.0.1", + nodeId: "56e81550db3ccbfb5eb69c0cfe3f4a7135c931a1bae79ea69a1a1c6092cdcbea4c76a556c3af977756f95d8bf9d7b38ab50ae070da390d3abb3d7e773099c1a9", + p2pPort: 21001, + raftId: 2, + raftPort: 50001 + }, { + ip: "127.0.0.1", + nodeId: "70399c3d1654c959a02b73acbdd4770109e39573a27a9b52bd391e5f79b91a42d8f2b9e982959402a97d2cbcb5656d778ba8661ec97909abc72e7bb04392ebd8", + p2pPort: 21000, + raftId: 1, + raftPort: 50000 + }] + > exit + ``` +6. Start your node by first creating a script as previous step and changing the ports you are going to use for Devp2p and raft. + ``` + $ cp startnode1.sh startnode2.sh + $ vim startnode2.sh + ..... paste below details + #!/bin/bash + PRIVATE_CONFIG=ignore nohup geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001 2>>node2.log & + + $ ./startnode2.sh + ``` + +7. Optional: share new `static-nodes.json` with all other chain participants + ``` + $ cp new-node-2/static-nodes.json new-node-1 + ``` + + Your additional node is now operational and is part of the same chain as the previously set up node. + +### Removing node +1. Connect to an already running node of the chain and execute `raft.cluster` and get the `RAFT_ID` corresponding to the node that needs to be removed +2. Run `raft.removePeer(RAFT_ID)` +3. Stop the `geth` process corresponding to the node that was removed. + ``` + $ geth attach new-node-1/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xedf53f5bf40c99f48df184441137659aed899c48 + at block: 0 (Thu, 01 Jan 1970 01:00:00 BST) + datadir: /Users/krish/fromscratch/new-node-1 + modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > raft.cluster + [{ + ip: "127.0.0.1", + nodeId: "56e81550db3ccbfb5eb69c0cfe3f4a7135c931a1bae79ea69a1a1c6092cdcbea4c76a556c3af977756f95d8bf9d7b38ab50ae070da390d3abb3d7e773099c1a9", + p2pPort: 21001, + raftId: 2, + raftPort: 50001 + }, { + ip: "127.0.0.1", + nodeId: "a5596803caebdc9c5326e1a0775563ad8e4aa14aa3530f0ae16d3fd8d7e48bc0b81342064e22094ab5d10303ab5721650af561f2bcdc54d705f8b6a8c07c94c3", + p2pPort: 21000, + raftId: 1, + raftPort: 50000 + }] + > + > raft.removePeer(2) + null + > raft.cluster + [{ + ip: "127.0.0.1", + nodeId: "a5596803caebdc9c5326e1a0775563ad8e4aa14aa3530f0ae16d3fd8d7e48bc0b81342064e22094ab5d10303ab5721650af561f2bcdc54d705f8b6a8c07c94c3", + p2pPort: 21000, + raftId: 1, + raftPort: 50000 + }] + > exit + $ + $ + $ ps | grep geth + PID TTY TIME CMD + 10554 ttys000 0:00.01 -bash + 9125 ttys002 0:00.50 -bash + 10695 ttys002 0:31.42 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpoo + 10750 ttys002 0:01.94 geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debu + $ kill 10750 + $ + $ + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.01 -bash + 9125 ttys002 0:00.51 -bash + 10695 ttys002 0:31.76 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpoo + ``` + + + +## Quorum with Istanbul BFT consensus +1. On each machine build Quorum as described in the [Installing](../Installing) section. Ensure that PATH contains geth and boot node + ``` + $ git clone https://github.com/jpmorganchase/quorum.git + $ cd quorum + $ make all + $ export PATH=$(pwd)/build/bin:$PATH + ``` +2. Install [istanbul-tools](https://github.com/jpmorganchase/istanbul-tools) + ``` + $ mkdir fromscratchistanbul + $ cd fromscratchistanbul + $ git clone https://github.com/jpmorganchase/istanbul-tools.git + $ cd istanbul-tools + $ make + ``` +3. Create a working directory for each of the X number of initial validator nodes + ``` + $ mkdir node0 node1 node2 node3 node4 + ``` +4. Change into the lead (whichever one you consider first) node's working directory and generate the setup files for X initial validator nodes by executing `istanbul setup --num X --nodes --quorum --save --verbose` **only execute this instruction once, i.e. not X times**. This command will generate several items of interest: `static-nodes.json`, `genesis.json`, and nodekeys for all the initial validator nodes which will sit in numbered directories from 0 to X-1 + ``` + $ cd node0 + $ ../istanbul-tools/build/bin/istanbul setup --num 5 --nodes --quorum --save --verbose + validators + { + "Address": "0x4c1ccd426833b9782729a212c857f2f03b7b4c0d", + "Nodekey": "fe2725c4e8f7617764b845e8d939a65c664e7956eb47ed7d934573f16488efc1", + "NodeInfo": "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@0.0.0.0:30303?discport=0" + } + { + "Address": "0x189d23d201b03ae1cf9113672df29a5d672aefa3", + "Nodekey": "3434f9efd184f2255f8acc9f4408a5068bd5ae920548044087578ab97ef22f3a", + "NodeInfo": "enode://1bb6be462f27e56f901c3fcb2d53a9273565f48e5d354c08f0c044405b29291b405b9f5aa027f3a75f9b058cb43e2f54719f15316979a0e5a2b760fff4631998@0.0.0.0:30303?discport=0" + } + { + "Address": "0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6", + "Nodekey": "8183051c9976200d245c59a80ae004f20c3f66e1aa1b8f17458931de91576e05", + "NodeInfo": "enode://0df02e94a3befc0683780d898119d3b675e5942c1a2f9ad47d35b4e6ccaf395cd71ec089fcf1d616748bf9871f91e5e3d29c1cf6f8f81de1b279082a104f619d@0.0.0.0:30303?discport=0" + } + { + "Address": "0xc1056df7c02b6f1a353052eaf0533cc7cb743b52", + "Nodekey": "de415c5dbbb9ff0a34dbd3bf871ee41b230f431925e1f4cc1dd225ef47cc066f", + "NodeInfo": "enode://3fe0ff0dd2730eaac7b6b379bdb51215b5831f4f48fa54a24a0298ad5ba8c2a332442948d53f4cd4fd28f373089a35e806ef722eb045659910f96a1278120516@0.0.0.0:30303?discport=0" + } + { + "Address": "0x7ae555d0f6faad7930434abdaac2274fd86ab516", + "Nodekey": "768b87473ba96fcfa272f958fc95a3cefdf9aa82110cde6f2f34aa5855eb39db", + "NodeInfo": "enode://e53e92e5a51ac2685b0406d0d3c62288b53831c3b0f492b9dc4bc40334783702cfa74c49b836efa2761edde33a3282704273b2453537b855e7a4aeadcccdb43e@0.0.0.0:30303?discport=0" + } + + + static-nodes.json + [ + "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@0.0.0.0:30303?discport=0", + "enode://1bb6be462f27e56f901c3fcb2d53a9273565f48e5d354c08f0c044405b29291b405b9f5aa027f3a75f9b058cb43e2f54719f15316979a0e5a2b760fff4631998@0.0.0.0:30303?discport=0", + "enode://0df02e94a3befc0683780d898119d3b675e5942c1a2f9ad47d35b4e6ccaf395cd71ec089fcf1d616748bf9871f91e5e3d29c1cf6f8f81de1b279082a104f619d@0.0.0.0:30303?discport=0", + "enode://3fe0ff0dd2730eaac7b6b379bdb51215b5831f4f48fa54a24a0298ad5ba8c2a332442948d53f4cd4fd28f373089a35e806ef722eb045659910f96a1278120516@0.0.0.0:30303?discport=0", + "enode://e53e92e5a51ac2685b0406d0d3c62288b53831c3b0f492b9dc4bc40334783702cfa74c49b836efa2761edde33a3282704273b2453537b855e7a4aeadcccdb43e@0.0.0.0:30303?discport=0" + ] + + + + genesis.json + { + "config": { + "chainId": 10, + "eip150Block": 1, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 1, + "eip158Block": 1, + "byzantiumBlock": 1, + "istanbul": { + "epoch": 30000, + "policy": 0 + }, + "isQuorum": true + }, + "nonce": "0x0", + "timestamp": "0x5cffc201", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f8aff869944c1ccd426833b9782729a212c857f2f03b7b4c0d94189d23d201b03ae1cf9113672df29a5d672aefa39444b07d2c28b8ed8f02b45bd84ac7d9051b3349e694c1056df7c02b6f1a353052eaf0533cc7cb743b52947ae555d0f6faad7930434abdaac2274fd86ab516b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", + "gasLimit": "0xe0000000", + "difficulty": "0x1", + "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "189d23d201b03ae1cf9113672df29a5d672aefa3": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "4c1ccd426833b9782729a212c857f2f03b7b4c0d": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "7ae555d0f6faad7930434abdaac2274fd86ab516": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "c1056df7c02b6f1a353052eaf0533cc7cb743b52": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + + $ ls -l + total 16 + drwxr-xr-x 9 krish staff 288 11 Jun 16:00 . + drwxr-xr-x 8 krish staff 256 11 Jun 15:58 .. + drwxr-xr-x 3 krish staff 96 11 Jun 16:00 0 + drwxr-xr-x 3 krish staff 96 11 Jun 16:00 1 + drwxr-xr-x 3 krish staff 96 11 Jun 16:00 2 + drwxr-xr-x 3 krish staff 96 11 Jun 16:00 3 + drwxr-xr-x 3 krish staff 96 11 Jun 16:00 4 + -rwxr-xr-x 1 krish staff 1878 11 Jun 16:00 genesis.json + -rwxr-xr-x 1 krish staff 832 11 Jun 16:00 static-nodes.json + ``` + +5. Update `static-nodes.json` to include the intended IP and port numbers of all initial validator nodes. In `static-nodes.json`, you will see a different row for each node. For the rest of the installation guide, row Y refers to node Y and row 1 is assumed to correspond to the lead node + ``` + $ cat static-nodes.json + .... update the IP and port numbers as give below... + [ + "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@127.0.0.1:30300?discport=0", + "enode://1bb6be462f27e56f901c3fcb2d53a9273565f48e5d354c08f0c044405b29291b405b9f5aa027f3a75f9b058cb43e2f54719f15316979a0e5a2b760fff4631998@127.0.0.1:30301?discport=0", + "enode://0df02e94a3befc0683780d898119d3b675e5942c1a2f9ad47d35b4e6ccaf395cd71ec089fcf1d616748bf9871f91e5e3d29c1cf6f8f81de1b279082a104f619d@127.0.0.1:30302?discport=0", + "enode://3fe0ff0dd2730eaac7b6b379bdb51215b5831f4f48fa54a24a0298ad5ba8c2a332442948d53f4cd4fd28f373089a35e806ef722eb045659910f96a1278120516@127.0.0.1:30303?discport=0", + "enode://e53e92e5a51ac2685b0406d0d3c62288b53831c3b0f492b9dc4bc40334783702cfa74c49b836efa2761edde33a3282704273b2453537b855e7a4aeadcccdb43e@127.0.0.1:30304?discport=0" + ] + ``` +6. In each node's working directory, create a data directory called `data`, and inside `data` create the `geth` directory + ``` + $ cd .. + $ mkdir -p node0/data/geth + $ mkdir -p node1/data/geth + $ mkdir -p node2/data/geth + $ mkdir -p node3/data/geth + $ mkdir -p node4/data/geth + ``` +7. Now we will generate initial accounts for any of the nodes in the required node's working directory. The resulting public account address printed in the terminal should be recorded. Repeat as many times as necessary. A set of funded accounts may be required depending what you are trying to accomplish + ``` + $ geth --datadir node0/data account new + INFO [06-11|16:05:53.672] Maximum peer count ETH=25 LES=0 total=25 + Your new account is locked with a password. Please give a password. Do not forget this password. + Passphrase: + Repeat passphrase: + Address: {8fc817d90f179b0b627c2ecbcc1d1b0fcd13ddbd} + $ geth --datadir node1/data account new + INFO [06-11|16:06:34.529] Maximum peer count ETH=25 LES=0 total=25 + Your new account is locked with a password. Please give a password. Do not forget this password. + Passphrase: + Repeat passphrase: + Address: {dce8adeef16a45d94be5e7804df6d35db834d94a} + $ geth --datadir node2/data account new + INFO [06-11|16:06:54.365] Maximum peer count ETH=25 LES=0 total=25 + Your new account is locked with a password. Please give a password. Do not forget this password. + Passphrase: + Repeat passphrase: + Address: {65a3ab6d4cf23395f544833831fc5d42a0b2b43a} + ``` +8. To add accounts to the initial block, edit the `genesis.json` file in the lead node's working directory and update the `alloc` field with the account(s) that were generated at previous step + ``` + $ vim node0/genesis.json + .... update the accounts under 'alloc' + { + "config": { + "chainId": 10, + "eip150Block": 1, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 1, + "eip158Block": 1, + "byzantiumBlock": 1, + "istanbul": { + "epoch": 30000, + "policy": 0 + }, + "isQuorum": true + }, + "nonce": "0x0", + "timestamp": "0x5cffc201", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f8aff869944c1ccd426833b9782729a212c857f2f03b7b4c0d94189d23d201b03ae1cf9113672df29a5d672aefa39444b07d2c28b8ed8f02b45bd84ac7d9051b3349e694c1056df7c02b6f1a353052eaf0533cc7cb743b52947ae555d0f6faad7930434abdaac2274fd86ab516b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", + "gasLimit": "0xe0000000", + "difficulty": "0x1", + "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "8fc817d90f179b0b627c2ecbcc1d1b0fcd13ddbd": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "dce8adeef16a45d94be5e7804df6d35db834d94a": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + }, + "65a3ab6d4cf23395f544833831fc5d42a0b2b43a": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ``` +9. Next we need to distribute the files created in part 4, which currently reside in the lead node's working directory, to all other nodes. To do so, place `genesis.json` in the working directory of all nodes, place `static-nodes.json` in the data folder of each node and place `X/nodekey` in node (X-1)'s `data/geth` directory + ``` + $ cp node0/genesis.json node1 + $ cp node0/genesis.json node2 + $ cp node0/genesis.json node3 + $ cp node0/genesis.json node4 + $ cp node0/static-nodes.json node0/data/ + $ cp node0/static-nodes.json node1/data/ + $ cp node0/static-nodes.json node2/data/ + $ cp node0/static-nodes.json node3/data/ + $ cp node0/static-nodes.json node4/data/ + $ cp node0/0/nodekey node0/data/geth + $ cp node0/1/nodekey node1/data/geth + $ cp node0/2/nodekey node2/data/geth + $ cp node0/3/nodekey node3/data/geth + $ cp node0/4/nodekey node4/data/geth + ``` +10. Switch into working directory of lead node and initialize it. Repeat for every working directory X created in step 3. *The resulting hash given by executing `geth init` must match for every node* + ``` + $ cd node0 + $ geth --datadir data init genesis.json + INFO [06-11|16:14:11.883] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:14:11.894] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node0/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:14:11.896] Writing custom genesis block + INFO [06-11|16:14:11.897] Persisted trie from memory database nodes=6 size=1.01kB time=76.665µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:11.897] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:14:11.897] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node0/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:14:11.898] Writing custom genesis block + INFO [06-11|16:14:11.898] Persisted trie from memory database nodes=6 size=1.01kB time=54.929µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:11.898] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ + $ cd .. + $ cd node1 + $ geth --datadir data init genesis.json + INFO [06-11|16:14:24.814] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:14:24.824] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node1/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:14:24.831] Writing custom genesis block + INFO [06-11|16:14:24.831] Persisted trie from memory database nodes=6 size=1.01kB time=82.799µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:24.832] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:14:24.832] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node1/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:14:24.833] Writing custom genesis block + INFO [06-11|16:14:24.833] Persisted trie from memory database nodes=6 size=1.01kB time=52.828µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:24.834] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ + $ cd .. + $ cd node2 + $ geth --datadir data init genesis.json + INFO [06-11|16:14:35.246] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:14:35.257] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node2/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:14:35.264] Writing custom genesis block + INFO [06-11|16:14:35.265] Persisted trie from memory database nodes=6 size=1.01kB time=124.91µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:35.265] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:14:35.265] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node2/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:14:35.267] Writing custom genesis block + INFO [06-11|16:14:35.268] Persisted trie from memory database nodes=6 size=1.01kB time=85.504µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:35.268] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ cd ../node3 + $ geth --datadir data init genesis.json + INFO [06-11|16:14:42.168] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:14:42.178] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node3/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:14:42.186] Writing custom genesis block + INFO [06-11|16:14:42.186] Persisted trie from memory database nodes=6 size=1.01kB time=124.611µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:42.187] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:14:42.187] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node3/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:14:42.189] Writing custom genesis block + INFO [06-11|16:14:42.189] Persisted trie from memory database nodes=6 size=1.01kB time=80.973µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:42.189] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ cd ../node4 + $ geth --datadir data init genesis.json + INFO [06-11|16:14:48.737] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:14:48.747] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node4/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:14:48.749] Writing custom genesis block + INFO [06-11|16:14:48.749] Persisted trie from memory database nodes=6 size=1.01kB time=71.213µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:48.750] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:14:48.750] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node4/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:14:48.751] Writing custom genesis block + INFO [06-11|16:14:48.751] Persisted trie from memory database nodes=6 size=1.01kB time=53.773µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:14:48.751] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ cd.. + ``` + +11. Start all nodes by first creating a script and running it. + ``` + $ vim startall.sh + .... paste below. The port numbers should match the port number for each node decided on in step 5 + #!/bin/bash + cd node0 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30300 2>>node.log & + + + cd ../node1 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30301 2>>node.log & + + cd ../node2 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22002 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30302 2>>node.log & + + cd ../node3 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22003 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30303 2>>node.log & + + cd ../node4 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22004 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30304 2>>node.log & + $ + See if the any geth nodes are running. + $ ps | grep geth + Kill geth processes + $ killall -INT geth + $ + $ chmod +x startall.sh + $ ./startall.sh + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.11 -bash + 21829 ttys001 0:00.03 -bash + 9125 ttys002 0:00.82 -bash + 36432 ttys002 0:00.19 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin, + 36433 ttys002 0:00.18 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin, + 36434 ttys002 0:00.19 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22002 --rpcapi admin, + 36435 ttys002 0:00.19 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22003 --rpcapi admin, + 36436 ttys002 0:00.19 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22004 --rpcapi admin, + $ + ``` + + !!! note + This configuration starts Quorum without privacy support as could be evidenced in prefix `PRIVATE_CONFIG=ignore`, please see below sections on [how to enable privacy with privacy transaction managers](#adding-privacy-transaction-manager). + Please note that istanbul-tools may be used to generate X number of nodes, more information is available in the [docs](https://github.com/jpmorganchase/istanbul-tools). + + Your node is now operational and you may attach to it with `geth attach node0/data/geth.ipc`. + +### Adding additional validator +1. Create a working directory for the new node that needs to be added + ``` + $ mkdir node5 + ``` +2. Change into the working directory for the new node and run `istanbul setup --num 1 --verbose --quorum --save`. This will generate the validator details including Address, NodeInfo and genesis.json + ``` + $ cd node5 + $ ../istanbul-tools/build/bin/istanbul setup --num 1 --verbose --quorum --save + validators + { + "Address": "0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", + "Nodekey": "25b47a49ef08f888c04f30417363e6c6bc33e739147b2f8b5377b3168f9f7435", + "NodeInfo": "enode://273eaf48591ce0e77c800b3e6465811d6d2f924c4dcaae016c2c7375256d17876c3e05f91839b741fe12350da0b5a741da4e30f39553fe8790f88503c64f6ef9@0.0.0.0:30303?discport=0" + } + + + + genesis.json + { + "config": { + "chainId": 10, + "eip150Block": 1, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 1, + "eip158Block": 1, + "byzantiumBlock": 1, + "istanbul": { + "epoch": 30000, + "policy": 0 + }, + "isQuorum": true + }, + "nonce": "0x0", + "timestamp": "0x5cffc942", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f85ad5942aabbc1bb9bacef60a09764d1a1f4f04a47885c1b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", + "gasLimit": "0xe0000000", + "difficulty": "0x1", + "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "2aabbc1bb9bacef60a09764d1a1f4f04a47885c1": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ``` + +3. Copy the address of the validator and run `istanbul.propose(
, true)` from more than half the number of current validators. + ``` + $ cd .. + $ geth attach node0/data/geth.ipc + $ geth attach node0/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0x4c1ccd426833b9782729a212c857f2f03b7b4c0d + at block: 137 (Tue, 11 Jun 2019 16:32:47 BST) + datadir: /Users/krish/fromscratchistanbul/node0/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > istanbul.getValidators() + ["0x189d23d201b03ae1cf9113672df29a5d672aefa3", "0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6", "0x4c1ccd426833b9782729a212c857f2f03b7b4c0d", "0x7ae555d0f6faad7930434abdaac2274fd86ab516", "0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"] + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",true) + null + $ + $ + $ geth attach node1/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0x189d23d201b03ae1cf9113672df29a5d672aefa3 + at block: 176 (Tue, 11 Jun 2019 16:36:02 BST) + datadir: /Users/krish/fromscratchistanbul/node1/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",true) + null + $ + $ + $ geth attach node2/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6 + at block: 179 (Tue, 11 Jun 2019 16:36:17 BST) + datadir: /Users/krish/fromscratchistanbul/node2/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",true) + null + $ + $ + $ geth attach node3/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52 + at block: 181 (Tue, 11 Jun 2019 16:36:27 BST) + datadir: /Users/krish/fromscratchistanbul/node3/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",true) + ``` + +4. Verify that the new validator has been added to the list of validators by running `istanbul.getValidators()` + ``` + ... you can see below command now displays 6 node address as validators. + > istanbul.getValidators() + ["0x189d23d201b03ae1cf9113672df29a5d672aefa3", "0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", "0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6", "0x4c1ccd426833b9782729a212c857f2f03b7b4c0d", "0x7ae555d0f6faad7930434abdaac2274fd86ab516", "0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"] + ``` +5. Copy `static-nodes.json` and genesis.json from the existing chain. `static-nodes.json` should be placed into new nodes data dir + ``` + $ cd node5 + $ mkdir -p data/geth + $ cp ../node0/static-nodes.json data + $ cp ../node0/genesis.json . + ``` +6. Edit `static-nodes.json` and add the new validators node info to the end of the file. New validators node info can be got from the output of `istanbul setup --num 1 --verbose --quorum --save` command that was run in step 2. Update the IP address and port of the node info to match the IP address of the validator and port you want to use. + ``` + $ vim data/static-nodes.json + ...add new validate nodes details with correct IP and port details + [ + "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@127.0.0.1:30300?discport=0", + "enode://1bb6be462f27e56f901c3fcb2d53a9273565f48e5d354c08f0c044405b29291b405b9f5aa027f3a75f9b058cb43e2f54719f15316979a0e5a2b760fff4631998@127.0.0.1:30301?discport=0", + "enode://0df02e94a3befc0683780d898119d3b675e5942c1a2f9ad47d35b4e6ccaf395cd71ec089fcf1d616748bf9871f91e5e3d29c1cf6f8f81de1b279082a104f619d@127.0.0.1:30302?discport=0", + "enode://3fe0ff0dd2730eaac7b6b379bdb51215b5831f4f48fa54a24a0298ad5ba8c2a332442948d53f4cd4fd28f373089a35e806ef722eb045659910f96a1278120516@127.0.0.1:30303?discport=0", + "enode://e53e92e5a51ac2685b0406d0d3c62288b53831c3b0f492b9dc4bc40334783702cfa74c49b836efa2761edde33a3282704273b2453537b855e7a4aeadcccdb43e@127.0.0.1:30304?discport=0", + "enode://273eaf48591ce0e77c800b3e6465811d6d2f924c4dcaae016c2c7375256d17876c3e05f91839b741fe12350da0b5a741da4e30f39553fe8790f88503c64f6ef9@127.0.0.1:30305?discport=0" + ] + + ``` +7. Copy the nodekey that was generated by `istanbul setup` command to the `geth` directory inside the working directory + ``` + $ cp 0/nodekey data/geth + ``` +8. Generate one or more accounts for this node and take down the account address. + ``` + $ geth --datadir data account new + INFO [06-12|17:45:11.116] Maximum peer count ETH=25 LES=0 total=25 + Your new account is locked with a password. Please give a password. Do not forget this password. + Passphrase: + Repeat passphrase: + Address: {37922bce824bca2f3206ea53dd50d173b368b572} + ``` +9. Initialize new node with below command + ``` + $ geth --datadir data init genesis.json + INFO [06-11|16:42:27.120] Maximum peer count ETH=25 LES=0 total=25 + INFO [06-11|16:42:27.130] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node5/data/geth/chaindata cache=16 handles=16 + INFO [06-11|16:42:27.138] Writing custom genesis block + INFO [06-11|16:42:27.138] Persisted trie from memory database nodes=6 size=1.01kB time=163.024µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:42:27.139] Successfully wrote genesis state database=chaindata hash=b992be…533db7 + INFO [06-11|16:42:27.139] Allocated cache and file handles database=/Users/krish/fromscratchistanbul/node5/data/geth/lightchaindata cache=16 handles=16 + INFO [06-11|16:42:27.141] Writing custom genesis block + INFO [06-11|16:42:27.142] Persisted trie from memory database nodes=6 size=1.01kB time=94.57µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B + INFO [06-11|16:42:27.142] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7 + $ + + ``` +10. Start the node by first creating below script and executing it: + ``` + $ cd .. + $ cp startall.sh start6.sh + $ vim start6.sh + ... paste below and update IP and port number matching for this node decided on step 6 + #!/bin/bash + cd node5 + PRIVATE_CONFIG=ignore nohup geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22005 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port 30305 2>>node.log & + $ + $ ./start6.sh + $ + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.11 -bash + 21829 ttys001 0:00.03 -bash + 9125 ttys002 0:00.93 -bash + 36432 ttys002 0:24.48 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin, + 36433 ttys002 0:23.36 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin, + 36434 ttys002 0:24.32 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22002 --rpcapi admin, + 36435 ttys002 0:24.21 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22003 --rpcapi admin, + 36436 ttys002 0:24.17 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22004 --rpcapi admin, + 36485 ttys002 0:00.15 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22005 --rpcapi admin, + 36455 ttys003 0:00.04 -bash + 36467 ttys003 0:00.32 geth attach node3/data/geth.ipc + ``` + +### Removing validator +1. Attach to a running validator and run `istanbul.getValidators()` and identify the address of the validator that needs to be removed + ``` + $ geth attach node0/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52 + at block: 181 (Tue, 11 Jun 2019 16:36:27 BST) + datadir: /Users/krish/fromscratchistanbul/node0/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + > istanbul.getValidators() + ["0x189d23d201b03ae1cf9113672df29a5d672aefa3", "0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", "0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6", "0x4c1ccd426833b9782729a212c857f2f03b7b4c0d", "0x7ae555d0f6faad7930434abdaac2274fd86ab516", "0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"] + ``` +2. Run `istanbul.propose(
, false)` by passing the address of the validator that needs to be removed from more than half current validators + ``` + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false) + null + $ + $ geth attach node1/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52 + at block: 181 (Tue, 11 Jun 2019 16:36:27 BST) + datadir: /Users/krish/fromscratchistanbul/node1/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false) + null + $ + $ geth attach node2/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52 + at block: 181 (Tue, 11 Jun 2019 16:36:27 BST) + datadir: /Users/krish/fromscratchistanbul/node2/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false) + null + $ + $ geth attach node3/data/geth.ipc + Welcome to the Geth JavaScript console! + + instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2 + coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52 + at block: 181 (Tue, 11 Jun 2019 16:36:27 BST) + datadir: /Users/krish/fromscratchistanbul/node3/data + modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 + > istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false) + null + ``` +3. Verify that the validator has been removed by running `istanbul.getValidators()` + ``` + > istanbul.getValidators() + ["0x189d23d201b03ae1cf9113672df29a5d672aefa3", "0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6", "0x4c1ccd426833b9782729a212c857f2f03b7b4c0d", "0x7ae555d0f6faad7930434abdaac2274fd86ab516", "0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"] + ``` +4. Stop the `geth` process corresponding to the validator that was removed. + ``` + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.11 -bash + 21829 ttys001 0:00.03 -bash + 9125 ttys002 0:00.94 -bash + 36432 ttys002 0:31.93 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin, + 36433 ttys002 0:30.75 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin, + 36434 ttys002 0:31.72 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22002 --rpcapi admin, + 36435 ttys002 0:31.65 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22003 --rpcapi admin, + 36436 ttys002 0:31.63 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22004 --rpcapi admin, + 36485 ttys002 0:06.86 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport 22005 --rpcapi admin, + 36455 ttys003 0:00.05 -bash + 36493 ttys003 0:00.22 geth attach node4/data/geth.ipc + $ kill 36485 + ``` + +### Adding non-validator node + +Same instructions as adding validator node **excluding** step 3 which proposes the node as validator. + +### Removing non-validator node + +Just execute **step 4** instruction from removing a validator node. + + +## Adding privacy transaction manager +### Tessera +1. Build Quorum and install [Tessera](https://github.com/jpmorganchase/tessera/releases) as described in the [Installing](../Installing) section. Ensure that PATH contains geth and bootnode. Be aware of the location of the `tessera.jar` release file + ``` + $ git clone https://github.com/jpmorganchase/quorum.git + $ cd quorum + $ make all + $ export PATH=$(pwd)/build/bin:$PATH + $ cd .. + .... copy tessera jar to your desired destination and rename it as tessera + $ mv tessera-app-0.9.2-app.jar tessera.jar + + ``` +2. Generate new keys using `java -jar /path-to-tessera/tessera.jar -keygen -filename new-node-1` + ``` + $ mkdir new-node-1t + $ cd new-node-1t + $ java -jar ../tessera.jar -keygen -filename new-node-1 + Enter a password if you want to lock the private key or leave blank + + Please re-enter the password (or lack of) to confirm + + 10:32:51.256 [main] INFO com.quorum.tessera.nacl.jnacl.Jnacl - Generating new keypair... + 10:32:51.279 [main] INFO com.quorum.tessera.nacl.jnacl.Jnacl - Generated public key PublicKey[pnesVeDgs805ZPbnulzC5wokDzpdN7CeYKVUBXup/W4=] and private key REDACTED + 10:32:51.624 [main] INFO c.q.t.k.generation.FileKeyGenerator - Saved public key to /Users/krish/fromscratch/new-node-1t/new-node-1.pub + 10:32:51.624 [main] INFO c.q.t.k.generation.FileKeyGenerator - Saved private key to /Users/krish/fromscratch/new-node-1t/new-node-1.key + ``` +3. Create new configuration file with newly generated keys referenced. Name it `config.json` as done in this example + ``` + vim config.json + { + "useWhiteList": false, + "jdbc": { + "username": "sa", + "password": "", + "url": "jdbc:h2:/yourpath/new-node-1t/db1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0", + "autoCreateTables": true + }, + "serverConfigs":[ + { + "app":"ThirdParty", + "enabled": true, + "serverAddress": "http://localhost:9081", + "communicationType" : "REST" + }, + { + "app":"Q2T", + "enabled": true, + "serverAddress":"unix:/yourpath/new-node-1t/tm.ipc", + "communicationType" : "REST" + }, + { + "app":"P2P", + "enabled": true, + "serverAddress":"http://localhost:9001", + "sslConfig": { + "tls": "OFF" + }, + "communicationType" : "REST" + } + ], + "peer": [ + { + "url": "http://localhost:9001" + }, + { + "url": "http://localhost:9003" + } + ], + "keys": { + "passwords": [], + "keyData": [ + { + "privateKeyPath": "/yourpath/new-node-1t/new-node-1.key", + "publicKeyPath": "/yourpath/new-node-1t/new-node-1.pub" + } + ] + }, + "alwaysSendTo": [] + } + ``` + +4. If you want to start another Tessera node, please repeat step 2 & step 3 + ``` + $ cd .. + $ mkdir new-node-2t + $ cd new-node-2t + $ java -jar ../tessera.jar -keygen -filename new-node-2 + Enter a password if you want to lock the private key or leave blank + + Please re-enter the password (or lack of) to confirm + + 10:45:02.567 [main] INFO com.quorum.tessera.nacl.jnacl.Jnacl - Generating new keypair... + 10:45:02.585 [main] INFO com.quorum.tessera.nacl.jnacl.Jnacl - Generated public key PublicKey[AeggpVlVsi+rxD6h9tcq/8qL/MsjyipUnkj1nvNPgTU=] and private key REDACTED + 10:45:02.926 [main] INFO c.q.t.k.generation.FileKeyGenerator - Saved public key to /Users/krish/fromscratch/new-node-2t/new-node-2.pub + 10:45:02.926 [main] INFO c.q.t.k.generation.FileKeyGenerator - Saved private key to /Users/krish/fromscratch/new-node-2t/new-node-2.key + $ + $ cp ../new-node-1t/config.json . + $ vim config.json + .... paste below + { + "useWhiteList": false, + "jdbc": { + "username": "sa", + "password": "", + "url": "jdbc:h2:yourpath/new-node-2t/db1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0", + "autoCreateTables": true + }, + "serverConfigs":[ + { + "app":"ThirdParty", + "enabled": true, + "serverAddress": "http://localhost:9083", + "communicationType" : "REST" + }, + { + "app":"Q2T", + "enabled": true, + "serverAddress":"unix:/yourpath/new-node-2t/tm.ipc", + "communicationType" : "REST" + }, + { + "app":"P2P", + "enabled": true, + "serverAddress":"http://localhost:9003", + "sslConfig": { + "tls": "OFF" + }, + "communicationType" : "REST" + } + ], + "peer": [ + { + "url": "http://localhost:9001" + }, + { + "url": "http://localhost:9003" + } + ], + "keys": { + "passwords": [], + "keyData": [ + { + "privateKeyPath": "/yourpath/new-node-2t/new-node-2.key", + "publicKeyPath": "/yourpath/new-node-2t/new-node-2.pub" + } + ] + }, + "alwaysSendTo": [] + } + + ``` +5. Start your Tessera nodes and send then into background + ``` + $ java -jar ../tessera.jar -configfile config.json >> tessera.log 2>&1 & + [1] 38064 + $ cd ../new-node-1t + $ java -jar ../tessera.jar -configfile config.json >> tessera.log 2>&1 & + [2] 38076 + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.12 -bash + 38234 ttys000 1:15.31 /usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python /usr/local/bin/mkdocs serve + 21829 ttys001 0:00.18 -bash + 9125 ttys002 0:01.52 -bash + 38072 ttys002 1:18.42 /usr/bin/java -jar ../tessera.jar -configfile config.json + 38076 ttys002 1:15.86 /usr/bin/java -jar ../tessera.jar -configfile config.json + ``` + +6. Start Quorum nodes attached to running Tessera nodes from above and send it to background + ``` + ... update the start scripts to include PRIVATE_CONFIG + $cd .. + $vim startnode1.sh + ... paste below + #!/bin/bash + PRIVATE_CONFIG=/yourpath/new-node-1t/tm.ipc nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 >> node.log 2>&1 & + $vim startnode2.sh + ... paste below + #!/bin/bash + PRIVATE_CONFIG=/yourpath/new-node-2t/tm.ipc nohup geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001 2>>node2.log & + $ ./startnode1.sh + $ ./startnode2.sh + $ ps + PID TTY TIME CMD + 10554 ttys000 0:00.12 -bash + 21829 ttys001 0:00.18 -bash + 9125 ttys002 0:01.49 -bash + 38072 ttys002 0:48.92 /usr/bin/java -jar ../tessera.jar -configfile config.json + 38076 ttys002 0:47.60 /usr/bin/java -jar ../tessera.jar -configfile config.json + 38183 ttys002 0:08.15 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpoo + 38204 ttys002 0:00.19 geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debu + 36455 ttys003 0:00.15 -bash + ``` + + !!! note + Tessera IPC bridge will be over a file name defined in your `config.json`, usually named `tm.ipc` as evidenced in prefix `PRIVATE_CONFIG=tm.ipc`. Your node is now able to send and receive private transactions, advertised public node key will be in the `new-node-1.pub` file. Tessera offers a lot of configuration flexibility, please refer [Configuration](../../Privacy/Tessera/Configuration/Configuration%20Overview) section under Tessera for complete and up to date configuration options. + + Your node is now operational and you may attach to it with `geth attach new-node-1/geth.ipc` to send private transactions. + ``` + $ vim private-contract.js + ... create simple private contract to send transaction from new-node-1 private for new-node-2's tessera public key created in step 4 + a = eth.accounts[0] + web3.eth.defaultAccount = a; + + // abi and bytecode generated from simplestorage.sol: + // > solcjs --bin --abi simplestorage.sol + var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"payable":false,"type":"constructor"}]; + + var bytecode = "0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029"; + + var simpleContract = web3.eth.contract(abi); + var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["AeggpVlVsi+rxD6h9tcq/8qL/MsjyipUnkj1nvNPgTU="]}, function(e, contract) { + if (e) { + console.log("err creating contract", e); + } else { + if (!contract.address) { + console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + } else { + console.log("Contract mined! Address: " + contract.address); + console.log(contract); + } + } + }); + $ + $ + ``` + + !!! note + Account opened in geth by default are locked, so please unlock account first before sending transaction + + ``` + $ + $ geth attach new-node-1/geth.ipc + > eth.accounts + ["0x23214cd88f46865207fa1d2a69971a37cdbf526a"] + > personal.unlockAccount("0x23214cd88f46865207fa1d2a69971a37cdbf526a"); + Unlock account 0x23214cd88f46865207fa1d2a69971a37cdbf526a + Passphrase: + true + > loadScript("private-contract.js") + Contract transaction send: TransactionHash: 0x7d3bf7612ef10c71f752e881648b7c8c4eee3223acab151ee0652447790836a6 waiting to be mined... + true + > Contract mined! Address: 0xe975e1e11c5268b1efcbf39b7ee3cf7b8dc85fd7 + ``` + + You have **successfully** sent a private transaction from node 1 to node 2 !! + + !!! note + if you do not have an valid public key in the array in private-contract.js, you will see the following error when the script in loaded. + ``` + > loadScript("private-contract.js") + err creating contract Error: Non-200 status code: &{Status:400 Bad Request StatusCode:400 Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Date:[Mon, 17 Jun 2019 15:23:53 GMT] Content-Type:[text/plain] Content-Length:[73] Server:[Jetty(9.4.z-SNAPSHOT)]] Body:0xc01997a580 ContentLength:73 TransferEncoding:[] Close:false Uncompressed:false Trailer:map[] Request:0xc019788200 TLS:} + ``` + +### Constellation +1. Build Quorum and install [Constellation](https://github.com/jpmorganchase/constellation/releases) as described in the [Installing](../Installing) section. Ensure that PATH contains geth, bootnode, and constellation-node binaries +2. Generate new keys with `constellation-node --generatekeys=new-node-1` +3. Start your constellation node and send it into background with `constellation-node --url=https://127.0.0.1:9001/ --port=9001 --workdir=. --socket=tm.ipc --publickeys=new-node-1.pub --privatekeys=new-node-1.key --othernodes=https://127.0.0.1:9001/ >> constellation.log 2>&1 &` +4. Start your node and send it into background with `PRIVATE_CONFIG=tm.ipc nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 2>>node.log &` + + !!! note + Constellation IPC bridge will be over a file name defined in your configuration: in above step #3 see option `--socket=file-name.ipc`. Your node is now able to send and receive private transactions, advertised public node key will be in the `new-node-1.pub` file. + + Your node is now operational and you may attach to it with `geth attach new-node-1/geth.ipc`. + + +## Enabling permissioned configuration +Quorum ships with a permissions system based on a custom whitelist. Detailed documentation is available in [Network Permissioning](../../Security/Framework/Quorum%20Network%20Security/Nodes/Permissioning/Network%20Permissioning). diff --git a/docs/Getting Started/Getting Started Overview.md b/docs/Getting Started/Getting Started Overview.md new file mode 100644 index 0000000000..d8d2fb4b9c --- /dev/null +++ b/docs/Getting Started/Getting Started Overview.md @@ -0,0 +1,15 @@ +# Getting Started Overview + +This section details several ways to start using and working with Quorum, ranging from using a pre-configured sample network running in a virtual machine, to creating a full network from scratch. + +## Quickstart with Quorum Examples' sample network + +The easiest way to get a network up and running is by working through the [Quorum Examples](../Quorum-Examples). These examples provide the means to create a pre-configured sample Quorum network that can be started and be ready for use in minutes. The examples give the option of running the network either in a virtual-machine environment using Vagrant, in containers using docker-compose, or locally through the use of bash scripts to automate creation of the network. + +## Creating a network from scratch + +[Creating a Network From Scratch](../Creating-A-Network-From-Scratch) provides a step-by-step walkthrough of how to create and configure a Quorum network suitable for either Raft or Istanbul consensus. It also shows how to enable privacy and add/remove nodes as required. + +## Creating a network deployed in the cloud + +[Quorum Cloud](https://github.com/jpmorganchase/quorum-cloud) provides an example of how a Quorum network can be run on a cloud platform. It uses Terraform to create a 7 node Quorum network deployed on AWS using AWS ECS Fargate, S3 and an EC2. diff --git a/docs/Getting Started/Getting-Started-From-Scratch.md b/docs/Getting Started/Getting-Started-From-Scratch.md deleted file mode 100644 index 10c03de458..0000000000 --- a/docs/Getting Started/Getting-Started-From-Scratch.md +++ /dev/null @@ -1,105 +0,0 @@ -# Getting started from scratch -## Quorum with Raft consensus -1. Build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and bootnode -2. Create a working directory which will be the base for the new node(s) and change into it -3. Generate one or more accounts for this node using `geth --datadir new-node-1 account new` and take down the account address. A funded account may be required depending what you are trying to accomplish -4. Create a `genesis.json` file see example [here](../genesis). The `alloc` field should be pre-populated with the account you generated at previous step -5. Generate node key `bootnode --genkey=nodekey` and copy it into datadir -6. Execute `bootnode --nodekey=new-node-1/nodekey --writeaddress` and take note of the displayed output. This is the enode id of the new node -7. Create a file called `static-nodes.json` and edit it to match this [example](../permissioned-nodes). Your file should contain a single line for your node with your enode's id and the ports you are going to use for devp2p and raft. Ensure that this file is in your nodes data directory -8. Initialize new node with `geth --datadir new-node-1 init genesis.json` -9. Start your node and send into background with `PRIVATE_CONFIG=ignore nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 2>>node.log &` - -Your node is now operational and you may attach to it with `geth attach new-node-1/geth.ipc`. This configuration starts Quorum without privacy support as could be evidenced in prefix `PRIVATE_CONFIG=ignore`, please see below sections on [how to enable privacy with privacy transaction managers](../Getting-Started-From-Scratch#adding-privacy-transaction-manager). - -### Adding additional node -1. Complete steps 1, 2, 5, and 6 from the previous guide -2. Retrieve current chains `genesis.json` and `static-nodes.json`. `static-nodes.json` should be placed into new nodes data dir -3. Initialize new node with `geth --datadir new-node-2 init genesis.json` -4. Edit `static-nodes.json` and add new entry for the new node you are configuring (should be last) -5. Connect to an already running node of the chain and execute `raft.addPeer('enode://new-nodes-enode-address-from-step-6-of-the-above@127.0.0.1:21001?discport=0&raftport=50001')` -6. Start your node and send into background with `PRIVATE_CONFIG=ignore nohup geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting RAFT_ID --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001 2>>node.log &`, where `RAFT_ID` is the response of the `raft.addPeer()` command in step 5. -7. Optional: share new `static-nodes.json` with all other chain participants - -Your additional node is now operational and is part of the same chain as the previously set up node. - -### Removing node -1. Connect to an already running node of the chain and execute `raft.cluster` and get the `RAFT_ID` corresponding to the node that needs to be removed -2. Run `raft.removePeer(RAFT_ID)` -3. Stop the `geth` process corresponding to the node that was removed. - - - -## Quorum with Istanbul BFT consensus -1. Build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and bootnode -2. Install [istanbul-tools](https://github.com/jpmorganchase/istanbul-tools) and place `istanbul` binary into PATH -3. Create a working directory for each of the X number of initial validator nodes -4. Change into the lead (whichever one you consider first) node's working directory and generate the setup files for X initial validator nodes by executing `istanbul setup --num X --nodes --quorum --save --verbose` **only execute this instruction once, i.e. not X times**. This command will generate several items of interest: `static-nodes.json`, `genesis.json`, and nodekeys for all the initial validator nodes which will sit in numbered directories from 0 to X-1 -5. Update `static-nodes.json` to include the intended IP and port numbers of all initial validator nodes. In `static-nodes.json`, you will see a different row for each node. For the rest of the installation guide, row Y refers to node Y and row 1 is assumed to correspond to the lead node -6. In each node's working directory, create a data directory called `data`, and inside `data` create the `geth` directory -7. Now we will generate initial accounts for any of the nodes by executing `geth --datadir data account new` in the required node's working directory. The resulting public account address printed in the terminal should be recorded. Repeat as many times as necessary. A set of funded accounts may be required depending what you are trying to accomplish -8. To add accounts to the initial block, edit the `genesis.json` file in the lead node's working directory and update the `alloc` field with the account(s) that were generated at previous step -9. Next we need to distribute the files created in part 4, which currently reside in the lead node's working directory, to all other nodes. To do so, place `genesis.json` in the working directory of all nodes, place `static-nodes.json` in the data folder of each node and place `X/nodekey` in node (X-1)'s `data/geth` directory -10. Switch into working directory of lead node and initialize it with `geth --datadir data init genesis.json`. Repeat for every working directory X created in step 3. *The resulting hash given by executing `geth init` must match for every node* -11. Start all nodes and send into background with `PRIVATE_CONFIG=ignore nohup geth --datadir data --permissioned --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport YOUR_NODES_RPC_PORT_NUMBER --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port YOUR_NODES_PORT_NUMBER 2>>node.log &`, remember to replace `YOUR_NODES_RPC_PORT_NUMBER` and `YOUR_NODES_PORT_NUMBER` with your node's designated port numbers. `YOUR_NODES_PORT_NUMBER` must match the port number for this node decided on in part 5 - -Your node is now operational and you may attach to it with `geth attach data/geth.ipc`. This configuration starts Quorum without privacy support as could be evidenced in prefix `PRIVATE_CONFIG=ignore`, please see below sections on [[how to enable privacy with privacy transaction managers|From-Scratch#adding-privacy-transaction-manager]]. - -Please note that istanbul-tools may be used to generate X number of nodes, more information is available in the [docs](https://github.com/jpmorganchase/istanbul-tools). - -### Adding additional validator -1. Create a working directory for the new node that needs to be added -2. Change into the working directory for the new node and run `istanbul setup --num 1 --verbose --quorum --save`. This will generate the validator details including Address, NodeInfo and genesis.json -3. Copy the address of the validator and run `istanbul.propose(
, true)` from more than half the number of current validators. -4. Verify that the new validator has been added to the list of validators by running `istanbul.getValidators()` -5. Build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth -6. Copy `static-nodes.json` and genesis.json from the existing chain. `static-nodes.json` should be placed into new nodes data dir -7. Edit `static-nodes.json` and add the new validators node info to the end of the file. New validators node info can be got from the output of `istanbul setup --num 1 --verbose --quorum --save` command that was run in step 2. Update the IP address and port of the node info to match the IP address of the validator and port you want to use. -8. Copy the nodekey that was generated by `istanbul setup` command to the `geth` directory inside the working directory -9. Generate one or more accounts for this node using `geth --datadir new-node-1 account new` and take down the account address. -10. Initialize new node with `geth --datadir new-node-1 init genesis.json` -11. Start the node and send into background with `PRIVATE_CONFIG=ignore nohup geth --datadir data --permissioned --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport YOUR_NODES_RPC_PORT_NUMBER --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port YOUR_NODES_PORT_NUMBER 2>>node.log &`, remember to replace `YOUR_NODES_RPC_PORT_NUMBER` and `YOUR_NODES_PORT_NUMBER` with your node's designated port numbers. `YOUR_NODES_PORT_NUMBER` must match the port number for this node decided on in part 7 - - -### Removing validator -1. Attach to a running validator and run `istanbul.getValidators()` and identify the address of the validator that needs to be removed -2. Run `istanbul.propose(
, false)` by passing the address of the validator that needs to be removed from more than half current validators -3. Verify that the validator has been removed by running `istanbul.getValidators()` -4. Stop the `geth` process corresponding to the validator that was removed. - -### Adding non-validator node -1. Create a working directory for the new node that needs to be added -2. Change into the working directory for the new node and run `istanbul setup --num 1 --verbose --quorum --save`. This will generate the node details including Address, NodeInfo and genesis.json -3. Build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth -4. Copy `static-nodes.json` and genesis.json from the existing chain. `static-nodes.json` should be placed into new nodes data dir -5. Edit `static-nodes.json` and add the new node info to the end of the file. New node info can be got from the output of `istanbul setup --num 1 --verbose --quorum --save` command that was run in step 2. Update the IP address and port of the node info to match the IP address of the validator and port you want to use. -6. Copy the nodekey that was generated by `istanbul setup` command to the `geth` directory inside the working directory -7. Generate one or more accounts for this node using `geth --datadir new-node-1 account new` and take down the account address. -8. Initialize new node with `geth --datadir new-node-1 init genesis.json` -9. Start the node and send into background with `PRIVATE_CONFIG=ignore nohup geth --datadir data --permissioned --nodiscover --istanbul.blockperiod 5 --syncmode full --verbosity 5 --networkid 10 --rpc --rpcaddr 0.0.0.0 --rpcport YOUR_NODES_RPC_PORT_NUMBER --rpcapi admin,db,eth,debug,net,shh,txpool,personal,web3,quorum,istanbul --emitcheckpoints --port YOUR_NODES_PORT_NUMBER 2>>node.log &`, remember to replace `YOUR_NODES_RPC_PORT_NUMBER` and `YOUR_NODES_PORT_NUMBER` with your node's designated port numbers. `YOUR_NODES_PORT_NUMBER` must match the port number for this node decided on in step 5 - -### Removing non-validator node -1. Stop the `geth` process corresponding to the node that needs to be removed. - - -## Adding privacy transaction manager -### Tessera -1. Build Quorum and install [Tessera](https://github.com/jpmorganchase/tessera/releases) as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and bootnode. Be aware of the location of the `tessera.jar` release file -2. Generate new keys using `java -jar /path-to-tessera/tessera.jar -keygen -filename new-node-1` -3. Create new configuration file referencing samples [here](../../Privacy/Tessera/Configuration/Sample%20Configuration) with newly generated keys referenced. Note the name of the file or name it `config.json` as done in this example -4. Start your tessera node and send it into background with `java -jar /path-to-tessera/tessera.jar -configfile config.json >> tessera.log 2>&1 &` -5. Start your node and send it into background with `PRIVATE_CONFIG=tm.ipc nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 2>>node.log &` - -Your node is now operational and you may attach to it with `geth attach new-node-1/geth.ipc`. Tessera IPC bridge will be over a file name defined in your `config.json`, usually named `tm.ipc` as evidenced in prefix `PRIVATE_CONFIG=tm.ipc`. Your node is now able to send and receive private transactions, advertised public node key will be in the `new-node-1.pub` file. Tessera offers a lot of configuration flexibility, please refer [Configuration](../../Privacy/Tessera/Configuration/Configuration%20Overview) section under Tessera for complete and up to date configuration options. - -### Constellation -1. Build Quorum and install [Constellation](https://github.com/jpmorganchase/constellation/releases) as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth, bootnode, and constellation-node binaries -2. Generate new keys with `constellation-node --generatekeys=new-node-1` -3. Start your constellation node and send it into background with `constellation-node --url=https://127.0.0.1:9001/ --port=9001 --workdir=. --socket=tm.ipc --publickeys=new-node-1.pub --privatekeys=new-node-1.key --othernodes=https://127.0.0.1:9001/ >> constellation.log 2>&1 &` -4. Start your node and send it into background with `PRIVATE_CONFIG=tm.ipc nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 2>>node.log &` - -Your node is now operational and you may attach to it with `geth attach new-node-1/geth.ipc`. Constellation IPC bridge will be over a file name defined in your configuration: in above step #3 see option `--socket=file-name.ipc`. Your node is now able to send and receive private transactions, advertised public node key will be in the `new-node-1.pub` file. - - -## Enabling permissioned configuration -Quorum ships with a permissions system based on a custom whitelist. Detailed documentation is available in [Network Permissioning](../../Security/Security%20%26%20Permissioning). diff --git a/docs/Getting Started/Installing.md b/docs/Getting Started/Installing.md new file mode 100644 index 0000000000..0b4ae727b8 --- /dev/null +++ b/docs/Getting Started/Installing.md @@ -0,0 +1,54 @@ +# Installing + +Quorum and its Privacy Managers can be installed and used as Docker containers, by building from source, or by downloading pre-built release binaries. + +## As containers +Docker containers exist for Quorum, Tessera and Constellation and can be found at the [`quorumengineering` Docker repository](https://hub.docker.com/u/quorumengineering/): + +``` +docker pull quorumengineering/quorum +docker pull quorumengineering/tessera +docker pull quorumengineering/constellation +``` + +## From source +### Quorum + +1. Clone the repository and build the source: + + ```bash + git clone https://github.com/jpmorganchase/quorum.git + cd quorum + make all + ``` + + Binaries are placed in `$REPO_ROOT/build/bin`. Add that folder to `PATH` to make `geth` and `bootnode` easily invokable, or copy those binaries to a folder already in `PATH`, e.g. `/usr/local/bin`. + + An easy way to supplement `PATH` is to add `PATH=$PATH:/path/to/repository/build/bin` to your `~/.bashrc` or `~/.bash_aliases` file. + +1. Run the tests: + + ```bash + make test + ``` + +### Privacy Managers + +#### Tessera +Tessera is a production-ready implementation of Quorum's privacy manager. It is undergoing active development with new features being added regularly. + +Follow the installation instructions on the [Tessera project page](https://github.com/jpmorganchase/tessera). + +#### Constellation +Constellation is the reference implementation of Quorum's privacy manager. It is still supported but no longer undergoing active development of new features. + +Grab a package for your platform [here](https://github.com/jpmorganchase/constellation/releases), and place the extracted binaries somewhere in `PATH`, e.g. `/usr/local/bin`. + +## As release binaries +The pre-compiled release binaries for Quorum, Tessera and Constellation can be downloaded from the following links: + +* [Quorum](https://github.com/jpmorganchase/quorum/releases) +* [Tessera](https://github.com/jpmorganchase/tessera/releases) +* [Constellation](https://github.com/jpmorganchase/constellation/releases) + +Once downloaded, add the binaries to `PATH` to make them easily invokable. diff --git a/docs/Getting Started/Quorum-Examples.md b/docs/Getting Started/Quorum-Examples.md index 936e9a3ec1..549aa1a5b2 100644 --- a/docs/Getting Started/Quorum-Examples.md +++ b/docs/Getting Started/Quorum-Examples.md @@ -1,181 +1,16 @@ -# Quorum Examples +# Examples -This section details couple of setup [examples for Quorum](https://github.com/jpmorganchase/quorum-examples.git) +The following is an incomplete list of official and unofficial projects and samples highlighting and showcasing functionality offered by Quorum platform. [quorum-examples](https://github.com/jpmorganchase/quorum-examples.git), is the official sample repository and it provides the means to easily create pre-configured networks for testing/development. Current examples include: -* [7nodes](../7Nodes): Starts up a fully-functioning Quorum environment consisting of 7 independent nodes. From this example one can test consensus, privacy, and all the expected functionality of an Ethereum platform. -* [5nodesRTGS](https://github.com/bacen/quorum-examples/tree/master/examples/5nodesRTGS): [__Note__: This links to an external repo which you will need to clone, thanks to @rsarres for this contribution!] Starts up a set of 5 nodes that simulates a Real-time Gross Setlement environment with 3 banks, one regulator (typically a central bank) and an observer that cannot access the private data. +* [7nodes](https://github.com/jpmorganchase/quorum-examples.git): Starts up a fully-functioning Quorum environment consisting of 7 independent nodes. This example demonstrates consensus, privacy, and all the expected functionality of an Ethereum platform. +* [5nodesRTGS](https://github.com/bacen/quorum-examples/tree/master/examples/5nodesRTGS): Starts up a set of 5 nodes that simulates a Real-time Gross Settlement environment with 3 banks, one regulator (typically a central bank) and an observer that cannot access the private data. +* [consistency-checker](https://github.com/miguelmartinezinf/consistency-checker): Consistency-checker enhances trust between parties involved in private smart contracts. This tool acts as an oracle, listening to modifications of a specific private contract on every participant node and publishing the unique state of the contract at every block height on a public contract. +* [web3j token sample](https://github.com/blk-io/quorum-sample): This project demonstrates the creation and management of a private token on a Quorum network. Quorum privacy is used, only certain members of the network are privy to the token that has been created. It is written in Java using web3j which is maintained by Web3 Labs. +* Pons [backend](https://github.com/M-Bowe/pons) | [frontend](https://github.com/M-Bowe/pons-frontend): A sample Cross-Chain Trading Bridge written to run over 2 Quorum Chains to safely exchange ERC-20 and ERC-721 assets. +* [Marketplace](https://github.com/lyotam/techmarketplace): Marketplace is an example application running on top of a Quorum network which allows users to bid for and offer virtual hackathon gear for sale in an interactive marketplace. This app is based on what was originally developed for the MLH Localhost Quorum workshop, which demonstrates how to run a simple Ethereum application and how to write a simple Smart Contract that interacts with the Ethereum-based network. -The easiest way to get started with running the examples is to use the vagrant environment (see below). -**Important note**: Any account/encryption keys contained in this repository are for -demonstration and testing purposes only. Before running a real environment, you should -generate new ones using Geth's `account` tool and the `--generate-keys` option for Constellation (or `-keygen` option for Tessera). - -## Getting Started -The 7nodes example can be run in three ways: - -1. By running a preconfigured Vagrant environment which comes complete with Quorum, Constellation, Tessera and the 7nodes example (__works on any machine__). -1. By running [`docker-compose`](https://docs.docker.com/compose/) against a preconfigured `compose` file ([example](https://github.com/jpmorganchase/quorum-examples/blob/master/docker-compose.yml) from the `quorum-examples` repo) which starts 7nodes example (tested on Windows 10, macOS Mojave & Ubuntu 18.04). -1. By downloading and locally running Quorum, Tessera and the examples (__requires an Ubuntu-based/macOS machine; note that Constellation does not support running locally__) - -### Setting up Vagrant -1. Install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) -2. Install [Vagrant](https://www.vagrantup.com/downloads.html) -3. Download and start the Vagrant instance (note: running `vagrant up` takes approx 5 mins): - - ```sh - git clone https://github.com/jpmorganchase/quorum-examples - cd quorum-examples - vagrant up - vagrant ssh - ``` - -4. To shutdown the Vagrant instance, run `vagrant suspend`. To delete it, run - `vagrant destroy`. To start from scratch, run `vagrant up` after destroying the - instance. - -#### Troubleshooting Vagrant -* If you are behind a proxy server, please see https://github.com/jpmorganchase/quorum/issues/23. -* If you are using macOS and get an error saying that the ubuntu/xenial64 image doesn't -exist, please run `sudo rm -r /opt/vagrant/embedded/bin/curl`. This is usually due to -issues with the version of curl bundled with Vagrant. -* If you receive the error `default: cp: cannot open '/path/to/geth.ipc' for reading: Operation not supported` after running `vagrant up`, run `./raft-init.sh` within the 7nodes directory on your local machine. This will remove temporary files created after running 7nodes locally and will enable `vagrant up` to execute correctly. - -#### Troubleshooting Vagrant: Memory usage -* The Vagrant instance is allocated 6 GB of memory. This is defined in the `Vagrantfile`, `v.memory = 6144`. This has been deemed a suitable value to allow the VM and examples to run as expected. The memory allocation can be changed by updating this value and running `vagrant reload` to apply the change. - -* If the machine you are using has less than 8 GB memory you will likely encounter system issues such as slow down and unresponsiveness when starting the Vagrant instance as your machine will not have the capacity to run the VM. There are several steps that can be taken to overcome this: - 1. Shutdown any running processes that are not required - 1. If running the [7nodes example](../7Nodes), reduce the number of nodes started up. See the [7nodes: Reducing the number of nodes](../7Nodes#reducing-the-number-of-nodes) for info on how to do this. - 1. Set up and run the examples locally. Running locally reduces the load on your memory compared to running in Vagrant. - -### Setting up Docker - -1. Install Docker (https://www.docker.com/get-started) - - If your Docker distribution does not contain `docker-compose`, follow [this](https://docs.docker.com/compose/install/) to install Docker Compose - - Make sure your Docker daemon has at least 4G memory - - Required Docker Engine 18.02.0+ and Docker Compose 1.21+ -1. Download and run `docker-compose` - ```sh - git clone https://github.com/jpmorganchase/quorum-examples - cd quorum-examples - docker-compose up -d - ``` -1. By default, Quorum Network is created using Tessera transaction manager and Istanbul BFT consensus. If you wish to change consensus configuration to Raft, set the environment variable `QUORUM_CONSENSUS=raft` before running `docker-compose` - ```sh - QUORUM_CONSENSUS=raft docker-compose up -d - ``` -1. Run `docker ps` to verify that all quorum-examples containers (7 nodes and 7 tx managers) are **healthy** -1. __Note__: to run the 7nodes demo, use the following snippet to open `geth` Javascript console to a desired node (using container name from `docker ps`) and send a private transaction - ```sh - $ docker exec -it quorum-examples_node1_1 geth attach /qdata/dd/geth.ipc - Welcome to the Geth JavaScript console! - - instance: Geth/node1-istanbul/v1.7.2-stable/linux-amd64/go1.9.7 - coinbase: 0xd8dba507e85f116b1f7e231ca8525fc9008a6966 - at block: 70 (Thu, 18 Oct 2018 14:49:47 UTC) - datadir: /qdata/dd - modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 - - > loadScript('/examples/private-contract.js') - ``` -1. Shutdown Quorum Network - ```sh - docker-compose down - ``` - -#### Troubleshooting Docker - -1. Docker is frozen - - Check if your Docker daemon is allocated enough memory (minimum 4G) -1. Tessera is crashed due to missing file/directory - - This is due to the location of `quorum-examples` folder is not shared - - Please refer to Docker documentation for more details: - - [Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/troubleshoot/#shared-drives) - - [Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/#file-sharing) - - [Docker Machine](https://docs.docker.com/machine/overview/): this depends on what Docker machine provider is used. Please refer to its documentation on how to configure shared folders/drives -1. If you run Docker inside Docker, make sure to run the container with `--privileged` - -### Setting up locally - -!!! info - This is only possible with Tessera. Constellation is not supported when running the examples locally. To use Constellation, the examples must be run in Vagrant. - -1. Install [Golang](https://golang.org/dl/) -2. Download and build [Quorum](https://github.com/jpmorganchase/quorum/): - - ```sh - git clone https://github.com/jpmorganchase/quorum - cd quorum - make - GETHDIR=`pwd`; export PATH=$GETHDIR/build/bin:$PATH - cd .. - ``` - -3. Download and build Tessera (see [README](https://github.com/jpmorganchase/tessera) for build options) - - ```bash - git clone https://github.com/jpmorganchase/tessera.git - cd tessera - mvn install - ``` - -4. Download quorum-examples - ```sh - git clone https://github.com/jpmorganchase/quorum-examples - ``` - -### Running the 7nodes example -Shell scripts are included in the examples to make it simple to configure the network and start submitting transactions. - -All logs and temporary data are written to the `qdata` folder. - -#### Using Raft consensus - -1. Navigate to the 7nodes example, configure the Quorum nodes and initialize accounts & keystores: - ```sh - cd path/to/7nodes - ./raft-init.sh - ``` -2. Start the Quorum and privacy manager nodes (Constellation or Tessera): - - If running in Vagrant: - ```sh - ./raft-start.sh - ``` - By default, Constellation will be used as the privacy manager. To use Tessera run the following: - ``` - ./raft-start.sh tessera - ``` - By default, `raft-start.sh` will look in `/home/vagrant/tessera/tessera-app/target/tessera-app-{version}-app.jar` for the Tessera jar. - - - If running locally with Tessera: - ``` - ./raft-start.sh tessera --tesseraOptions "--tesseraJar /path/to/tessera-app.jar" - ``` - - The Tessera jar location can also be specified by setting the environment variable `TESSERA_JAR`. - -3. You are now ready to start sending private/public transactions between the nodes - -#### Using Istanbul BFT consensus -To run the example using __Istanbul BFT__ consensus use the corresponding commands: -```sh -istanbul-init.sh -istanbul-start.sh -istanbul-start.sh tessera -stop.sh -``` - -#### Using Clique POA consensus -To run the example using __Clique POA__ consensus use the corresponding commands: -```sh -clique-init.sh -clique-start.sh -clique-start.sh tessera -stop.sh -``` - -### Next steps: Sending transactions -Some simple transaction contracts are included in quorum-examples to demonstrate the privacy features of Quorum. To learn how to use them see the [7nodes](../7Nodes). +!!! Info + Most of the links link out to externally maintained repos. We thank all of the authors. Please contact us for any modifications or questions about the content. diff --git a/docs/Getting Started/Setup Overview & Quickstart.md b/docs/Getting Started/Setup Overview & Quickstart.md deleted file mode 100644 index c640ac578e..0000000000 --- a/docs/Getting Started/Setup Overview & Quickstart.md +++ /dev/null @@ -1,33 +0,0 @@ -# Setup Overview & Quickstart - -Using Quorum requires that a Quorum Node and a Constellation/Tessera Node are installed, configured and -running (see build/installation instructions for both below). An overview of the steps to follow to manually set up Quorum, including key generation, genesis block & Constellation/Tessera configuration will be available soon, but for now the best way to get started is to use the Vagrant environment that has been made available for running the [Quorum Examples](../Quorum-Examples). The Vagrant environment automatically sets up a test Quorum network that is ready for development use within minutes and is the recommended approach if you are looking to get started with Quorum. If you don't want to use the Quorum Examples approach and instead would like to manually set up Quorum then please see below (Note: this documentation is Work In Progress) - -## Building Quorum Node From Source - -Clone the repository and build the source: - -``` -git clone https://github.com/jpmorganchase/quorum.git -cd quorum -make all -``` - -Binaries are placed in `$REPO_ROOT/build/bin`. Put that folder in your PATH to make `geth` and `bootnode` easily invokable, or copy those binaries to a folder already in PATH, e.g. `/usr/local/bin`. - -An easy way to supplement PATH is to add `PATH=$PATH:/path/to/repository/build/bin` to your `~/.bashrc` or `~/.bash_aliases` file. - -Run the tests: - -``` -make test -``` - -## Installing Constellation -Grab a package for your platform [here](https://github.com/jpmorganchase/constellation/releases), and place the extracted binaries somewhere in PATH, e.g. /usr/local/bin. - -## Installing Tessera -Follow the installation instructions on the [Tessera project page](https://github.com/jpmorganchase/tessera). - -## Getting Started from Scratch -Follow the instructions given [here](../Getting-Started-From-Scratch). diff --git a/docs/api.md b/docs/Getting Started/api.md similarity index 97% rename from docs/api.md rename to docs/Getting Started/api.md index 45f731f644..baec9d57c2 100644 --- a/docs/api.md +++ b/docs/Getting Started/api.md @@ -62,21 +62,22 @@ web3.eth.sendRawPrivateTransaction(signedTransactionData [, privateData] [, call Sends a pre-signed transaction. For example can be signed using: https://github.com/SilentCicero/ethereumjs-accounts -__Important:__ Please note that before calling this API, a `storeraw` api need to be called first to Quorum's private transaction manager. Instructions on how to do this can be found [here](https://github.com/jpmorganchase/tessera/wiki/Interface-&-API). +__Important:__ Please note that before calling this API, a `storeraw` api need to be called first to Quorum's private transaction manager. Instructions on how to do this can be found [here](../../Privacy/Tessera/Usage/Interface%20&%20API/). ##### Parameters 1. `String` - Signed transaction data in HEX format 2. `Object` - Private data to send - `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. +3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. - ##### 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. + If the transaction was a contract creation use `web3.eth.getTransactionReceipt()` 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" }); - ``` +``` @@ -208,7 +209,7 @@ curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0", "method":"eth_getQ submitting the transaction; a server must be set up to receive POST requests at the given URL. - ##### Parameters +##### Parameters 1. `Object` - The transaction object to send: - `from`: `String` - The address for the sending account. Uses the `web3.eth.defaultAccount` property, if not specified. @@ -222,7 +223,7 @@ curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0", "method":"eth_getQ - `privateFor`: `List` - (optional) When sending a private transaction, an array of the recipients' base64-encoded public keys. - `callbackUrl`: `String` - (optional) the URL to perform a POST request to to post the result of submitted the transaction - ##### Returns +##### Returns 1. `String` - The empty hash, defined as `0x0000000000000000000000000000000000000000000000000000000000000000` diff --git a/docs/Getting Started/running.md b/docs/Getting Started/running.md index fcd9feeda5..09783a27e8 100644 --- a/docs/Getting Started/running.md +++ b/docs/Getting Started/running.md @@ -27,7 +27,7 @@ Example JSON RPC API call to send a public transaction: } ``` -See the [Quorum API](../../api) page for details on the `sendTransaction` call, which includes some modifications to the standard Ethereum call. +See the [Quorum API](../api) page for details on the `sendTransaction` call, which includes some modifications to the standard Ethereum call. !!! info See the Contract Design Considerations sections below for important points on creating Quorum contracts @@ -56,7 +56,7 @@ Example JSON RPC API call to send a private transaction: } ``` -See the [Quorum API](../../api) page for details on the `sendTransaction` call, which includes some modifications to the standard Ethereum call. +See the [Quorum API](../api) page for details on the `sendTransaction` call, which includes some modifications to the standard Ethereum call. !!! info See the Contract Design Considerations sections below for important points on creating Quorum contracts @@ -171,7 +171,7 @@ Any additions to the `permissioned-nodes.json` file will be dynamically picked u Removing existing connected nodes from the `permissioned-nodes.json` file will not immediately drop those existing connected nodes. However, if the connection is dropped for any reason, and a subsequent connect request is made from the dropped node ids, it will be rejected as part of that new request. ## Quorum API -Please see the [Quorum API](../../api) page for details. +Please see the [Quorum API](../api) page for details. ## Network and Chain ID @@ -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/How-To-Guides/add_ibft_validator.md b/docs/How-To-Guides/add_ibft_validator.md new file mode 100644 index 0000000000..8c16336c05 --- /dev/null +++ b/docs/How-To-Guides/add_ibft_validator.md @@ -0,0 +1,291 @@ +# Adding and removing IBFT validators + +Over the lifetime of an IBFT network, validators will need to be added and removed as authorities change. +Here we will showcase adding a new validator to an IBFT network, as well as removing an existing one. + +## Adding a node to the validator set + +Adding a node to the IBFT validator set is relatively easy once a node is part of the network. +It does not matter whether the node is already online or not, as the process to add the new node as a validator only +needs the *existing* validators. + +!!! warning + If you are adding multiple validators before they are brought online, make sure you don't go over the BFT limit and cause the chain to stop progressing. + +Adding a new validator requires that a majority of existing validators propose the new node to be added. This is +achieved by calling the `propose` RPC method with the value `true` and replacing the address to your required one: + + ```bash + $ geth attach /qdata/dd/geth.ipc + + > istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", true); + null + ``` + +This indicates that the current node wishes to add address `0xb131288f355bc27090e542ae0be213c20350b767` as a new +validator. + +### Example + +You can find the resources required to run the examples in the +[quorum-examples](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/ibft_validator_set_changes) +repository. + +1. The examples use `docker-compose` for the container definitions. If you are following along by copying the commands + described, then it is important to set the project name for Docker Compose, or to remember to change the prefix for + your directory. See [Docker documentation](https://docs.docker.com/compose/reference/envvars/#compose_project_name) + for more details. + + To set the project name, run the following: + ```bash + $ export COMPOSE_PROJECT_NAME=addnode + ``` + +2. Bring up the network, which contains 7 nodes, of which 6 are validators. + + ```bash + $ docker-compose -f ibft-6-validators.yml up + ``` + + We will be adding the 7th node as a validator. You may notice in the logs of node 7 messages along the lines of + `node7_1 | WARN [01-20|10:37:16.034] Block sealing failed err=unauthorized`. This is because + the node was started up with minting enabled, but doesn't have the authority to create blocks, and so throws this + error. + +3. Now we need to propose node 7 as a new proposer from the existing nodes. + + !!! note + Remember, you could do this stage before starting node 7 in your network + + We need a majority of existing validators to propose the new node before the changes will take effect. + + Lets start with node 1 and see what happens: + + ```bash + # Propose node 7 from node 1 + $ docker exec -it addnode_node1_1 geth --exec 'istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", true);' attach /qdata/dd/geth.ipc + null + + # Wait about 5 seconds, and then run: + $ docker exec -it addnode_node1_1 geth --exec 'istanbul.getSnapshot();' attach /qdata/dd/geth.ipc + { + epoch: 30000, + hash: "0xf814863d809ce3a683ee0a2197b15a8152d2696fc9c4e47cd82d0bd5cdaa3e45", + number: 269, + policy: 0, + tally: { + 0xb131288f355bc27090e542ae0be213c20350b767: { + authorize: true, + votes: 1 + } + }, + validators: ["0x6571d97f340c8495b661a823f2c2145ca47d63c2", "0x8157d4437104e3b8df4451a85f7b2438ef6699ff", "0xb912de287f9b047b4228436e94b5b78e3ee16171", "0xd8dba507e85f116b1f7e231ca8525fc9008a6966", "0xe36cbeb565b061217930767886474e3cde903ac5", "0xf512a992f3fb749857d758ffda1330e590fa915e"], + votes: [{ + address: "0xb131288f355bc27090e542ae0be213c20350b767", + authorize: true, + block: 268, + validator: "0xd8dba507e85f116b1f7e231ca8525fc9008a6966" + }] + } + ``` + + Let's break this down. + Firstly, we proposed the address `0xb131288f355bc27090e542ae0be213c20350b767` to be added; that is what the `true` + parameter is for. If we had set it to `false`, that means we want to remove an existing validator with that address. + + Secondly, we fetched the current snapshot, which gives us an insight into the current running state of the voting. + We can see that the new address has 1 vote under the `tally` section, and that one vote is described under the + `votes` section. So we know our vote was registered! + +4. Let's run this from node 2 and see similar results: + + ```bash + $ docker exec -it addnode_node2_1 geth --exec 'istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", true);' attach /qdata/dd/geth.ipc + null + + # Again, you may have to wait 5 - 10 seconds for the snapshot to show the vote + $ docker exec -it addnode_node2_1 geth --exec 'istanbul.getSnapshot();' attach /qdata/dd/geth.ipc + { + epoch: 30000, + hash: "0x93efcd458f3b875902a4532bb77d5e7ebb701791ea95486ecd58baf682312d74", + number: 391, + policy: 0, + tally: { + 0xb131288f355bc27090e542ae0be213c20350b767: { + authorize: true, + votes: 2 + } + }, + validators: ["0x6571d97f340c8495b661a823f2c2145ca47d63c2", "0x8157d4437104e3b8df4451a85f7b2438ef6699ff", "0xb912de287f9b047b4228436e94b5b78e3ee16171", "0xd8dba507e85f116b1f7e231ca8525fc9008a6966", "0xe36cbeb565b061217930767886474e3cde903ac5", "0xf512a992f3fb749857d758ffda1330e590fa915e"], + votes: [{ + address: "0xb131288f355bc27090e542ae0be213c20350b767", + authorize: true, + block: 388, + validator: "0xd8dba507e85f116b1f7e231ca8525fc9008a6966" + }, { + address: "0xb131288f355bc27090e542ae0be213c20350b767", + authorize: true, + block: 390, + validator: "0x6571d97f340c8495b661a823f2c2145ca47d63c2" + }] + } + ``` + + True to form, we have the second vote registered! + +5. Ok, let's finally vote on nodes 3 and 4. + + ```bash + $ docker exec -it addnode_node3_1 geth --exec 'istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", true);' attach /qdata/dd/geth.ipc + null + + $ docker exec -it addnode_node4_1 geth --exec 'istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", true);' attach /qdata/dd/geth.ipc + null + ``` + +6. Now we have a majority of votes, let's check the snapshot again: + + ```bash + docker exec -it addnode_node1_1 geth --exec 'istanbul.getSnapshot();' attach /qdata/dd/geth.ipc + { + epoch: 30000, + hash: "0xd4234184538297f71f5b7024a2e11f51f06b4f569ebd9e3644abd391b8c66101", + number: 656, + policy: 0, + tally: {}, + validators: ["0x6571d97f340c8495b661a823f2c2145ca47d63c2", "0x8157d4437104e3b8df4451a85f7b2438ef6699ff", "0xb131288f355bc27090e542ae0be213c20350b767", "0xb912de287f9b047b4228436e94b5b78e3ee16171", "0xd8dba507e85f116b1f7e231ca8525fc9008a6966", "0xe36cbeb565b061217930767886474e3cde903ac5", "0xf512a992f3fb749857d758ffda1330e590fa915e"], + votes: [] + } + ``` + + We can see that the votes have now been wiped clean, ready for a new round. Additionally, the address we were adding, + `0xb131288f355bc27090e542ae0be213c20350b767` now exists within the `validators` list! + Lastly, the `unauthorized` messages that node 7 was giving before has stopped, as it now has the authority to mint + blocks. + +## Removing a node from the validator set + +Removing a validator is very similar to adding a node, but this time we want to propose nodes with the value `false`, +to indicate we are deauthorising them. It does not matter whether the node is still online or not, as it doesn't +require any input from the node being removed. + +!!! warning + Be aware when removing nodes that cross the BFT boundary, e.g. going from 10 validators to 9, as this may impact the chains ability to progress if other nodes are offline + +Removing a new validator requires that a majority of existing validators propose the new node to be removed. This is +achieved by calling the `propose` RPC method with the value `false` and replacing the address to your required one: + + ```bash + $ geth attach /qdata/dd/geth.ipc + + > istanbul.propose("0xb131288f355bc27090e542ae0be213c20350b767", false); + null + ``` + +### Example + +You can find the resources required to run the examples in the +[quorum-examples](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/ibft_validator_set_changes) +repository. + +1. The examples use `docker-compose` for the container definitions. If you are following along by copying the commands + described, then it is important to set the project name for Docker Compose, or to remember to change the prefix for + your directory. See [Docker documentation](https://docs.docker.com/compose/reference/envvars/#compose_project_name) + for more details. + + To set the project name, run the following: + ```bash + $ export COMPOSE_PROJECT_NAME=addnode + ``` + +2. Bring up the network, which contains 7 nodes, of which 6 are validators. + + ```bash + # Set the environment variable for docker-compose + $ export COMPOSE_PROJECT_NAME=addnode + + # Start the 7 node network, of which 6 are validators + $ docker-compose -f ibft-6-validators.yml up + ``` + +3. Now we need to propose node 6 as the node to remove. + + !!! note + We need a majority of existing validators to propose the new node before the changes will take effect. + + Lets start with node 1 and see what happens: + + ```bash + # Propose node 7 from node 1 + $ docker exec -it addnode_node1_1 geth --exec 'istanbul.propose("0x8157d4437104e3b8df4451a85f7b2438ef6699ff", false);' attach /qdata/dd/geth.ipc + null + + # Wait about 5 seconds, and then run: + $ docker exec -it addnode_node1_1 geth --exec 'istanbul.getSnapshot();' attach /qdata/dd/geth.ipc + { + epoch: 30000, + hash: "0xba9f9b72cad90ae8aee39f352b45f21d5ed5535b4479743e3f39b231fd717792", + number: 140, + policy: 0, + tally: { + 0x8157d4437104e3b8df4451a85f7b2438ef6699ff: { + authorize: false, + votes: 1 + } + }, + validators: ["0x6571d97f340c8495b661a823f2c2145ca47d63c2", "0x8157d4437104e3b8df4451a85f7b2438ef6699ff", "0xb912de287f9b047b4228436e94b5b78e3ee16171", "0xd8dba507e85f116b1f7e231ca8525fc9008a6966", "0xe36cbeb565b061217930767886474e3cde903ac5", "0xf512a992f3fb749857d758ffda1330e590fa915e"], + votes: [{ + address: "0x8157d4437104e3b8df4451a85f7b2438ef6699ff", + authorize: false, + block: 136, + validator: "0xd8dba507e85f116b1f7e231ca8525fc9008a6966" + }] + } + ``` + + Let's break this down. + Firstly, we proposed the address `0x8157d4437104e3b8df4451a85f7b2438ef6699ff` to be removed; that is what the + `false` parameter is for. + + Secondly, we fetched the current snapshot, which gives us an insight into the current running state of the voting. + We can see that the proposed address has 1 vote under the `tally` section, and that one vote is described under the + `votes` section. Here, the `authorize` section is set to `false`, which is inline with our proposal to *remove* the + validator. + +4. We need to get a majority, so let's run the proposal on 3 more nodes: + + ```bash + $ docker exec -it addnode_node2_1 geth --exec 'istanbul.propose("0x8157d4437104e3b8df4451a85f7b2438ef6699ff", false);' attach /qdata/dd/geth.ipc + null + + $ docker exec -it addnode_node3_1 geth --exec 'istanbul.propose("0x8157d4437104e3b8df4451a85f7b2438ef6699ff", false);' attach /qdata/dd/geth.ipc + null + + $ docker exec -it addnode_node4_1 geth --exec 'istanbul.propose("0x8157d4437104e3b8df4451a85f7b2438ef6699ff", false);' attach /qdata/dd/geth.ipc + null + ``` + +5. Let's check the snapshot now all the required votes are in: + + ```bash + $ docker exec -it addnode_node1_1 geth --exec 'istanbul.getSnapshot();' attach /qdata/dd/geth.ipc + { + epoch: 30000, + hash: "0x25815a32b086926875ea2c44686e4b20effabc731b2b121ebf0e0f395101eea5", + number: 470, + policy: 0, + tally: {}, + validators: ["0x6571d97f340c8495b661a823f2c2145ca47d63c2", "0xb912de287f9b047b4228436e94b5b78e3ee16171", "0xd8dba507e85f116b1f7e231ca8525fc9008a6966", "0xe36cbeb565b061217930767886474e3cde903ac5", "0xf512a992f3fb749857d758ffda1330e590fa915e"], + votes: [] + } + ``` + + The validator has been removed from the `validators` list, and we are left with the other 5 still present. You will + also see in the logs of node 6 a message like + `node6_1 | WARN [01-20|11:35:52.044] Block sealing failed err=unauthorized`. This is because it is still minting + blocks, but realises it does not have the authority to push them to any of the other nodes on the network (you will + also see this message for node 7, which was never authorised but still set up to mine). + +## See also + +- [Adding a new node to the network](/How-To-Guides/adding_nodes) \ No newline at end of file diff --git a/docs/How-To-Guides/add_node_examples.md b/docs/How-To-Guides/add_node_examples.md new file mode 100644 index 0000000000..047dc0366b --- /dev/null +++ b/docs/How-To-Guides/add_node_examples.md @@ -0,0 +1,388 @@ +# Node addition examples + +Below are some scenarios for adding a new node into a network, with a mix of different options such as +consensus algorithm, permissioning and discovery. + +You can find the resources required to run the examples in the +[quorum-examples](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/adding_nodes) repository. +Checkout the repository through `git` or otherwise download all the resources your local machine to follow along. + +The examples use `docker-compose` for the container definitions. If you are following along by copying the commands +described, then it is important to set the project name for Docker Compose, or to remember to change the prefix for +your directory. See [Docker documentation](https://docs.docker.com/compose/reference/envvars/#compose_project_name) +for more details. + +To set the project name, run the following: +```bash +$ export COMPOSE_PROJECT_NAME=addnode +``` + +## Non-permimssioned IBFT with discovery + +An example using IBFT, no permissioning and discover enabled via a bootnode. +There are no static peers in this network; instead, every node is set to talk to node 1 via the CLI flag +`--bootnodes enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@172.16.239.11:21000`. +Node 1 will forward the details of all the nodes it knows about (in this case, everyone) and they will then initiate their +own connections. + +1. Bring up an initial network of 6 nodes. + + ```bash + # Ensure any old network is removed + $ docker-compose -f ibft-non-perm-bootnode.yml down + + # Bring up 6 nodes + $ docker-compose -f ibft-non-perm-bootnode.yml up node1 node2 node3 node4 node5 node6 + ``` + +2. Send in a public transaction and check it is minted. + + !!! note + * The block creation period is set to 2 seconds, so you may have to wait upto that amount of time for the transaction to be minted. + * The transaction hashes will likely be different, but the contract addresses will be the same for your network. + + ```bash + # Send in the transaction + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909 waiting to be mined... + true + + # Retrieve the value of the contract + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + + We created a transaction, in this case with hash `0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909`, + and then retrieved its value, which was set to be `42`. + +3. Bring up the last node. This node also has its bootnodes set to be node 1, so at startup will try to establish a +connection to node 1 only. After this, node 1 will share which nodes it knows about, and node 7 can then initiate +connections with those peers. + + ```bash + # Bring up node 7 + $ docker-compose -f ibft-non-perm-bootnode.yml up node7 + ``` + +4. Let's check to see if the nodes are in sync. If they are, they will have similar block numbers, which is enough for +this example; there are other ways to tell if nodes are on the same chain, e.g. matching block hashes. + + !!! note + Depending on timing, the second may have an extra block or two. + + ```bash + # Fetch the latest block number for node 1 + $ docker exec -it addnode_node1_1 geth --exec 'eth.blockNumber' attach /qdata/dd/geth.ipc + 45 + + # Fetch the latest block number for node 7 + $ docker exec -it addnode_node7_1 geth --exec 'eth.blockNumber' attach /qdata/dd/geth.ipc + 45 + ``` + +5. We can check that the transaction and contract we sent earlier now exist on node 7. + + ```bash + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +6. To be sure we have two way communication, let's send a transaction from node 7 to the network. + + ```bash + $ docker exec -it addnode_node7_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0x84cefc3aab8ce5797dc73c70db604e5c8830fc7c2cf215876eb34fff533e2725 waiting to be mined... + true + ``` + +7. Finally, we can check if the transaction was minted and the contract executed on each node. + + ```bash + # Check on node 1 + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + + # Check on node 7 + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +And that's it. We deployed a working 6 node network, and then added a 7th node afterwards; this 7th node was able to +read existing public data, as well as deploy its own transactions and contracts for others to see! + +## Non-permissioned RAFT with discovery disabled + +This example walks through adding a new node to a RAFT network. This network does not have permissioning for the +Ethereum peer-to-peer layer, and makes it connections solely based on who is listed in the nodes `static-nodes.json` +file. + +1. Bring up an initial network of 6 nodes. + + ```bash + # Ensure any old network is removed + $ docker-compose -f raft-non-perm-nodiscover.yml down + + # Bring up 6 nodes + $ docker-compose -f raft-non-perm-nodiscover.yml up node1 node2 node3 node4 node5 node6 + ``` + +2. Send in a public transaction and check it is minted. + + !!! note + * The transaction hashes will likely be different, but the contract addresses will be the same for your network. + + ```bash + # Send in the transaction + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909 waiting to be mined... + true + + # Retrieve the value of the contract + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + + We created a transaction, in this case with hash `0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909`, + and then retrieved its value, which was set to be `42`. + +3. We need to add the new peer to the RAFT network before it joins, otherwise the existing nodes will reject it from +the RAFT communication layer; we also need to know what ID the new node should join with. + + ```bash + # Add the new node + $ docker exec -it addnode_node1_1 geth --exec 'raft.addPeer("enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@172.16.239.17:21000?discport=0&raftport=50400")' attach /qdata/dd/geth.ipc + 7 + ``` + + The return value is the RAFT ID of the new node. When the node joins the network for the first time, it will need + this ID number handy. If it was lost, you can always view the full network, including IDs, by running the + `raft.cluster` command on an existing node. + +4. Bring up the last node. Here, we pass the newly created ID number as a flag into the startup of node 7. This lets +the node know to not bootstrap a new network from the contents of `static-nodes.json`, but to connect to an existing +node there are fetch any bootstrap information. + + ```bash + # Bring up node 7 + $ QUORUM_GETH_ARGS="--raftjoinexisting 7" docker-compose -f raft-non-perm-nodiscover.yml up node7 + ``` + +5. Let's check to see if the nodes are in sync. We can do by seeing if we have the contract that we viewer earlier on +node 7. + + ```bash + # Fetch the contracts value on node 7 + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +6. To be sure we have two way communication, let's send a transaction from node 7 to the network. + + ```bash + $ docker exec -it addnode_node7_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0x84cefc3aab8ce5797dc73c70db604e5c8830fc7c2cf215876eb34fff533e2725 waiting to be mined... + true + ``` + +7. Finally, we can check if the transaction was minted and the contract executed on each node. + + ```bash + # Check on node 1 + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + + # Check on node 7 + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +And that's it. We deployed a working 6 node network, and then added a 7th node afterwards; this 7th node was able to +read existing public data, as well as deploy its own transactions and contracts for others to see! + +## Permissioned RAFT with discovery disabled + +This example walks through adding a new node to a RAFT network. This network does have permissioning enabled for the +Ethereum peer-to-peer layer; this means that for any Ethereum tasks, such as syncing the initial blockchain or +propagating transactions, the node must appear is others nodes' `permissioned-nodes.json` file. + +1. Bring up an initial network of 6 nodes. + + ```bash + # Ensure any old network is removed + $ docker-compose -f raft-perm-nodiscover.yml down + + # Bring up 6 nodes + $ docker-compose -f raft-perm-nodiscover.yml up node1 node2 node3 node4 node5 node6 + ``` + +2. Send in a public transaction and check it is minted. + + !!! note + * The transaction hashes will likely be different, but the contract addresses will be the same for your network. + + ```bash + # Send in the transaction + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909 waiting to be mined... + true + + # Retrieve the value of the contract + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + + We created a transaction, in this case with hash `0xd1bf0c15546802e5a121f79d0d8e6f0fa45d4961ef8ab9598885d28084cfa909`, + and then retrieved its value, which was set to be `42`. + +3. We need to add the new peer to the RAFT network before it joins, otherwise the existing nodes will reject it from +the RAFT communication layer; we also need to know what ID the new node should join with. + + ```bash + # Add the new node + $ docker exec -it addnode_node1_1 geth --exec 'raft.addPeer("enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@172.16.239.17:21000?discport=0&raftport=50400")' attach /qdata/dd/geth.ipc + 7 + ``` + + The return value is the RAFT ID of the new node. When the node joins the network for the first time, it will need + this ID number handy. If it was lost, you can always view the full network, including IDs, by running the + `raft.cluster` command on an existing node. + +4. Bring up the last node. Here, we pass the newly created ID number as a flag into the startup of node 7. This lets +the node know to not bootstrap a new network from the contents of `static-nodes.json`, but to connect to an existing +node there are fetch any bootstrap information. + + ```bash + # Bring up node 7 + $ QUORUM_GETH_ARGS="--raftjoinexisting 7" docker-compose -f raft-non-perm-nodiscover.yml up node7 + ``` + +5. Let's check to see if the nodes are in sync. We can do by seeing if we have the contract that we viewer earlier on +node 7. + + ```bash + # Fetch the contracts value on node 7 + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 0 + ``` + + The value here is `0`, not the expected `42`! Node 7 is unable to sync the blockchain because the other peers in the + network are refusing to allow connections from node 7, due to it being missing in the `permissioned-nodes.json` file. + + This does not affect the RAFT layer, so if node 7 was already is sync, it could still receive new blocks; this is + okay though, since it would be permissioned on the RAFT side by virtue of being part of the RAFT cluster. + +6. Let's update the permissioned nodes list on node 1, which will allow node 7 to connect to it. + + ```bash + $ docker exec -it addnode_node1_1 cp /extradata/static-nodes-7.json /qdata/dd/permissioned-nodes.json + $ + ``` + +7. Node 7 should now be synced up through node 1. Let's see if we can see the contract we made earlier. + + !!! note + Quorum attempts to re-establish nodes every 30 seconds, so you may have to wait for the sync to happen. + + ```bash + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +8. To be sure we have two way communication, let's send a transaction from node 7 to the network. + + ```bash + $ docker exec -it addnode_node7_1 geth --exec 'loadScript("/examples/public-contract.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0x84cefc3aab8ce5797dc73c70db604e5c8830fc7c2cf215876eb34fff533e2725 waiting to be mined... + true + ``` + +9. Finally, we can check if the transaction was minted and the contract executed on each node. + + ```bash + # Check on node 1 + $ docker exec -it addnode_node1_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + + # Check on node 7 + $ docker exec -it addnode_node7_1 geth --exec 'var private = eth.contract([{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"}]).at("0x1349f3e1b8d71effb47b840594ff27da7e603d17"); private.get();' attach /qdata/dd/geth.ipc + 42 + ``` + +And that's it. We deployed a working 6 node network, and then added a 7th node afterwards; this 7th node was able to + read existing public data, as well as deploy its own transactions and contracts for others to see! + +## Adding a Private Transaction Manager + +This is a simple example of adding a new Tessera instance to an existing network. For simplicity, +the steps to add the Quorum node are omitted, but are those followed in the IBFT example. +Here, a Tessera node is added without any of the discovery options specified, meaning that the +IP Whitelist isn't used, nor is key discovery disabled. + +1. Start up the initial 6 node network. + + ```bash + # Ensure any old network is removed + $ docker-compose -f tessera-add.yml down + + # Bring up 6 nodes + $ docker-compose -f tessera-add.yml up node1 node2 node3 node4 node5 node6 + ``` + +2. We can verify that private transactions can be sent by sending one from node 1 to node 6. +We can also see that since node 7 doesn't exist yet, we can't send private transactions to it. + + ```bash + # Send a private transaction from node 1 to node 6 + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/private-contract-6.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0xc8a5de4bb79d4a8c3c1156917968ca9b2965f2514732fc1cff357ec999b9aba4 waiting to be mined... + true + # Success! + + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/private-contract-7.js")' attach /qdata/dd/geth.ipc + err creating contract Error: Non-200 status code: &{Status:404 Not Found StatusCode:404 Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Server:[Jetty(9.4.z-SNAPSHOT)] Date:[Thu, 16 Jan 2020 12:44:19 GMT] Content-Type:[text/plain] Content-Length:[73]] Body:0xc028e87d40 ContentLength:73 TransferEncoding:[] Close:false Uncompressed:false Trailer:map[] Request:0xc000287200 TLS:} + true + # An expected failure. The script content didn't succeed, but the script itself was run okay, so true was still returned + ``` + +3. Let's first bring up node 7, then we can inspect what is happening and the configuration used. + + ```bash + # Bring up node 7 + $ docker-compose -f tessera-add.yml up node7 + + $ docker exec -it addnode_node7_1 cat /qdata/tm/tessera-config.json + # ...some output... + ``` + + The last command will output Tessera 7's configuration. + The pieces we are interested in here are the following: + + ```json + { + "useWhiteList": false, + "peer": [ + { + "url": "http://txmanager1:9000" + } + ], + ... + } + ``` + + We can see that the whitelist is not enabled, discovery is not specified so defaults to enabled, + and we have a single peer to start off with, which is node 1. + This is all that is needed to connect to an existing network. Shortly after starting up, Tessera + will ask node 1 about all it's peers, and then will keep a record of them for it's own use. From + then on, all the nodes will know about node 7 and can send private transactions to it. + +4. Let's try it! Let's send a private transaction from node 1 to the newly added node 7. + + ```bash + # Sending a transaction from node 1 to node 7 + $ docker exec -it addnode_node1_1 geth --exec 'loadScript("/examples/private-contract-7.js")' attach /qdata/dd/geth.ipc + Contract transaction send: TransactionHash: 0x3e3b50768ffdb51979677ddb58f48abdabb82a3fd4f0bac5b3d1ad8014e954e9 waiting to be mined... + true + ``` + + We got a success this time! Tessera 7 has been accepted into the network and can interact with the + other existing nodes. \ No newline at end of file diff --git a/docs/How-To-Guides/adding_nodes.md b/docs/How-To-Guides/adding_nodes.md new file mode 100644 index 0000000000..3201c922b0 --- /dev/null +++ b/docs/How-To-Guides/adding_nodes.md @@ -0,0 +1,227 @@ +# Adding nodes to the network + +Adding new nodes to an existing network can range from a common occurence to never happening. +In public blockchains, such as the Ethereum Mainnet, new nodes continuously join and talk to the existing network. +In permissioned blockchains, this may not happen as often, but it still an important task to achieve as your network +evolves. + +When adding new nodes to the network, it is important understand that the Quorum network and Private Transaction +Manager network are distinct and do not overlap in any way. Therefore, options applicable to one are not applicable to +the other. In some cases, they may have their own options to achieve similar tasks, but must be specified separately. + +## Prerequisites + +- [Quorum installed](/Getting%20Started/Installing.md) +- [Tessera/Constellation installed](/Getting%20Started/Installing.md) if using private transactions +- A running network (see [Creating a Network From Scratch](/Getting%20Started/Creating-A-Network-From-Scratch)) + +## Adding Quorum nodes + +Adding a new Quorum node is the most common operation, as you can choose to run a Quorum node with or without a Private +Transaction Manager, but rarely will one do the opposite. + +### Raft + +1. On an *existing* node, add the new peer to the raft network + ``` + > raft.addPeer("enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407") + 7 + ``` + + So in this example, our new node has a Raft ID of `7`. + +2. If you are using permissioning, or discovery for Ethereum p2p, please refer [here](#extra-options). + +3. We now need to initialise the new node with the network's genesis configuration. + + !!! note + Where you obtain this from will be dependent on the network. You may get it from an existing peer, or a network operator, or elsewhere entirely. + + Initialising the new node is exactly the same an the original nodes. + ```bash + $ geth --datadir qdata/dd7 init genesis.json + ``` + +4. Now we can start up the new node and let it sync with the network. The main difference now is the use of the +`--raftjoinexisting` flag, which lets the node know that it is joining an existing network, which is handled +differently internally. The Raft ID obtained in step 1 is passed as a parameter to this flag. + + ```bash + $ PRIVATE_CONFIG=ignore geth --datadir qdata/dd7 ... OTHER ARGS ... --raft --raftport 50407 --rpcport 22006 --port 21006 --raftjoinexisting 7 + ``` + + The new node is now up and running, and will start syncing the blockchain from existing peers. Once this has + completed, it can send new transactions just as any other peer. + +### IBFT/Clique + +Adding nodes to an IBFT/Clique network is a bit simpler, as it only needs to configure itself rather then be +pre-allocated on the network (permissioning aside). + +1. Initialise the new node with the network's genesis configuration. + + !!! note + Where you obtain this from will be dependent on the network. You may get it from an existing peer, or a network operator, or elsewhere entirely. + + Initialising the new node is exactly the same an the original nodes. + ```bash + $ geth --datadir qdata/dd7 init genesis.json + ``` + +2. If you are using permissioning or discovery for Ethereum peer-to-peer, please refer [here](#extra-options). + +3. Start the new node, pointing either to a `bootnode` or listing an existing peer in the `static-nodes.json` file. +Once a connection is established, the node will start syncing the blockchain, after which transactions can be sent. + +### Extra options + +Some options take effect regardless of the consensus mechanism used. + +#### Permissioned nodes + +If using the `permissioned-nodes.json` file for permissioning, then you must make sure this file is updated on all +nodes before the new node is able to communicate with existing nodes. You do not need to restart any nodes in +order for the changes to take effect. + +#### Static node connections + +If not using peer-to-peer node discovery (i.e. you have specified `--nodiscover`), then the only connections a node +made will be to peers defined in the `static-nodes.json` file. When adding a new node, you should make sure you have +peers defined in its `static-nodes.json` file. The more peers you have defined here, the better network connectivity +and fault tolerance you have. + +!!! note + * You do not need to update the existing peers static nodes for the connection to be established, although it is good practise to do so. + * You do not need to specify every peer in your static nodes file if you do not wish to connect to every peer directly. + +#### Peer-to-peer discovery + +If you are using discovery, then more options *in addition* to static nodes become available. + +- Any nodes that are connected to your peers, which at the start will be ones defined in the static node list, will +then be visible by you, allowing you to connect to them; this is done automatically. + +- You may specify any number of bootnodes, defined by the `--bootnodes` parameter. This takes a commas separated list +of enode URIs, similar to the `static-nodes.json` file. These act in the same way as static nodes, letting you connect +to them and then find out about other peers, whom you then connect to. + +!!! note + If you have discovery disabled, this means you will not try to find other nodes to connect to, but others can still find and connect to you. + +## Adding Private Transaction Managers + +In this tutorial, there will be no focus on the advanced features of adding a new Private Transaction Manager (PTM). +This tutorial uses [Tessera](https://github.com/jpmorganchase/tessera) for any examples. + +Adding a new node to the PTM is relatively straight forward, but there are a lot of extra options that can be used, +which is what will be explained here. + +### Adding a new PTM node + +In a basic setting, adding a new PTM node is as simple as making sure you have one of the existing nodes listed in your +peer list. + +In Tessera, this would equate to the following in the configuration file: +```json +{ + "peers": [ + { + "url": "http://existingpeer1.com:8080" + } + ] +} +``` + +From there, Tessera will connect to that peer and discover all the other PTM nodes in the network, connecting to each +of them in turn. + +!!! note + You may want to include multiple peers in the peer list in case any of them are offline/unreachable. + +### IP whitelisting + +The IP Whitelist that Tessera provides allows you restrict connections much like the `permissioned-nodes.json` file +does for Quorum. Only IP addresses/hostnames listed in your peers list will be allowed to connect to you. + +See the [Tessera configuration page](/Privacy/Tessera/Configuration/Configuration%20Overview#whitelist) for details on setting it up. + +In order to make sure the new node is accepted into the network: + +1. You will need to add the new peer to each of the existing nodes before communication is allowed. + Tessera provides a way to do this without needing to restart an already running node: + ```bash + $ java -jar tessera.jar admin -configfile /path/to/existing-node-config.json -addpeer http://newpeer.com:8080 + ``` + +2. The new peer can be started, setting the `peers` configuration to mirror the existing network. + e.g. if there are 3 existing nodes in the network, then the new nodes configuration will look like this: + ```json + { + "peers": [ + { + "url": "http://existingpeer1.com:8080" + }, + { + "url": "http://existingpeer2.com:8080" + }, + { + "url": "http://existingpeer3.com:8080" + } + ] + } + ``` + + The new node will allow incoming connections from the existing peers, and then existing peers will allow incoming + connections from the new peer! + +### Discovery + +Tessera discovery is very similar to the IP whitelist. The difference being that the IP whitelist blocks +communications between nodes, whereas disabling discovery only affects which public keys we keep track of. + +See the [Tessera configuration page](/Privacy/Tessera/Configuration/Configuration%20Overview#disabling-peer-discovery) for +details on setting it up. + +When discovery is disabled, Tessera will only allow keys that are owned by a node in its peer list to be available to +the users. This means that if any keys are found that are owned by a node NOT in our peer list, they are discarded and +private transactions cannot be sent to that public key. + +!!! note + This does not affect incoming transactions. Someone not in your peer list can still send transactions to your node, unless you also enable the IP Whitelist option. + + + +In order to make sure the new node is accepted into the network: + +1. You will need to add the new peer to each of the existing nodes before they will accept public keys that are linked +to the new peer. + Tessera provides a way to do this without needing to restart an already running node: + ```bash + $ java -jar tessera.jar admin -configfile /path/to/existing-node-config.json -addpeer http://newpeer.com:8080 + ``` + +2. The new peer can be started, setting the `peers` configuration to mirror the existing network. + e.g. if there are 3 existing nodes in the network, then the new nodes configuration will look like this: + ```json + { + "peers": [ + { + "url": "http://existingpeer1.com:8080" + }, + { + "url": "http://existingpeer2.com:8080" + }, + { + "url": "http://existingpeer3.com:8080" + } + ] + } + ``` + + The new node will now record public keys belonging to the existing peers, and then existing peers will record + public keys belonging to the new peer; this allows private transactions to be sent both directions! + + +## Examples + +For a walkthrough of some examples that put into action the above, check out [this guide](/How-To-Guides/add_node_examples)! \ No newline at end of file diff --git a/docs/Permissioning/Contract Design.md b/docs/Permissioning/Contract Design.md new file mode 100644 index 0000000000..742c7d59e7 --- /dev/null +++ b/docs/Permissioning/Contract Design.md @@ -0,0 +1,21 @@ +# Smart Contract design for permissions +The permissions model is completely built on smart contracts. The smart contract design is as below: +![contract design](images/ContractDesign.png) + +The permissions smart contract design follows the Proxy-Implementation-Storage pattern which allows the implementation logic to change without changing the storage or interface layer. A brief description of the smart contracts is below: + +* `PermissionsUpgradable.sol`: This contract stores the address of current implementation contract and is owned by a guardian (an Ethereum account). Only the guardian is allowed to change the implementation contract address. +* `PermissionsInterface.sol`: This is the interface contract and holds the interfaces for permissions related actions. It has no business logic and forwards requests to the current implementation contract +* `PermissionsImplementation.sol`: This contract has the business logic for the permissions actions. It can receive requests only from a valid interface as defined in `PermissionsUpgradable.sol` and interacts with all the storage contracts for respective actions. +* `OrgManager.sol`: This contract stores data for organizations and sub organizations. It can receive requests from a valid implementation contract as defined in `PermissionsUpgrdable.sol` +* `AccountManager.sol`: This contract receives requests from a valid implementation contract as defined in `PermissionsUpgrdable.sol`. It stores the data of all accounts, their linkage to organization and various roles. The contract also stores the status of an account. The account can be in any of the following status - `PendingApproval`, `Active`, `Inactive`, `Suspended`, `Blacklisted` or `Revoked` +* `NodeManager.sol`: This contract receives requests from a valid implementation contract as defined in `PermissionsUpgrdable.sol`. It stores the data of a node, its linkage to an organization or sub organization, and status of the node. The node can be in any one of the following status - `PendingApproval`, `Approved`, `Deactivated` or `Blacklisted` +* `RoleManager.sol`: This contract receives requests from a valid implementation contract as defined in `PermissionsUpgrdable.sol`. It stores data for various roles and the organization to which it is linked. The access at role level can be any one of the following: + - `Readonly` which allows only read operations + - `Transact` which allows value transfer but no contract deployment access + - `ContractDeploy` which allows both value transfer and contract deployment access + - `FullAccess` which allows additional network level accesses in addition to value transfer and contract deployment + + If a role is revoked all accounts which are linked to the role lose all access rights + +* `VoterManager.sol`: This contract receives requests from a valid implementation contract as defined in `PermissionsUpgrdable.sol`. It stores the data of valid voters at network level which can approve identified activities e.g. adding a new organization to the network. Any account which is linked to a predefined network admin role will be marked as a voter. Whenever a network level activity which requires voting is performed, a voting item is added to this contract and each voter account can vote for the activity. The activity is marked as `Approved` upon majority voting. diff --git a/docs/Permissioning/Overview.md b/docs/Permissioning/Overview.md new file mode 100644 index 0000000000..f34cc0bc1e --- /dev/null +++ b/docs/Permissioning/Overview.md @@ -0,0 +1,16 @@ +# Introduction +The [current permission model](../Old%20Permissioning) within Quorum is limited to node level permissions only and allows a set of nodes which are part of `permissioned-nodes.json` to join the network. The model has been enhanced to cater for enterprise level needs to have a **smart contract based permission model**; this has the flexibility to manage nodes, accounts and account level access controls. The overview of the model is as depicted below: +![permissions mode](images/PermissionsModel.png) +### Key Definitions +* Network - A set of interconnected nodes representing an enterprise blockchain which contains organizations +* Organization - A set of roles, Ethereum accounts and nodes having a variety of permissions to interact with the network +* Sub Organization - Further sub-grouping within the Organization as per business needs +* Account - An Ethereum account which is an EOA (Externally Owned Account) +* Voter - An account capable of voting for a certain action +* Role - A named job function in an organization +* Node - A `geth` node which is part of the network and belongs to an organization or sub organization + +As depicted above, in the enhanced permissions model, the network comprises a group of organizations. The network admin accounts defined at network level can propose and approve new organizations to join the network, and can assign an account as the organization administration account. The organization admin account can create roles, create sub organizations, assign roles to its accounts, and add any other node which is part of the organization. A sub organization can have its own set of roles, accounts and sub organizations. The organization administration account manages and controls all activities at the organization level. The organization administrator can create an admin role and assign the same to a different account to manage the administration of a sub organization. The access rights of an account are derived based on the role assigned to it. The account will be able to transact via any node linked to the sub org or at overall organizations level. + +A sample network view is as depicted below: +![sample mode](images/sampleNetwork.png) diff --git a/docs/Permissioning/Permissioning apis.md b/docs/Permissioning/Permissioning apis.md new file mode 100644 index 0000000000..a6cca2b22e --- /dev/null +++ b/docs/Permissioning/Permissioning apis.md @@ -0,0 +1,868 @@ +# Permission APIs +## APIs +### `quorumPermission_orgList` +Returns the list of all organizations with the status of each organization in the network +#### Parameters +None +#### Returns +* `fullOrgId`: complete org id including the all parent org ids separated by ".". +* `level`: level of the org in org hierarchy +* `orgId`: organization identifier +* `parentOrgId`: immediate parent org id +* `status`: org status. [refer](#organization-status-types) for complete list of statuses +* `subOrgList`: list of sub orgs linked to the org +* `ultimateParent`: Master org under which the org falls +#### Examples +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_orgList","id":10}' --header "Content-Type: application/json" + +// Response +{ + fullOrgId: "INITORG", + level: 1, + orgId: "INITORG", + parentOrgId: "", + status: 2, + subOrgList: null, + ultimateParent: "INITORG" +} +``` + +```javascript tab="geth console" +> quorumPermission.orgList +[{ + fullOrgId: "INITORG", + level: 1, + orgId: "INITORG", + parentOrgId: "", + status: 2, + subOrgList: null, + ultimateParent: "INITORG" +}] +``` +### `quorumPermission_acctList` +Returns the list of accounts permissioned in the network + +#### Parameters +None + +#### Returns +* `acctId`: account id +* `isOrgAdmin`: indicates if the account is admin account for the organization +* `orgId`: org identifier +* `roleId`: role assigned to the account +* `status`: account status. [refer](#account-status-types) for the complete list of account status. + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_acctList","id":10}' --header "Content-Type: application/json" + +// Response +{ + acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 +}, { + acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 +} +``` + +```javascript tab="geth console" +> quorumPermission.acctList +[{ + acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 +}, { + acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 +}] +``` +### `quorumPermission_nodeList` +Returms the list of nodes part of the network +#### Parameters +None +#### Returns +* `orgId`: org id to which the node belongs +* `status`: status of the node. [refer](#node-status-types) for the complete list of node statuses +* `url`: complete enode id +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_nodeList","id":10}' --header "Content-Type: application/json" + +// Response +{ + orgId: "INITORG", + status: 2, + url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" +} +``` + +```javascript tab="geth console" +> quorumPermission.nodeList +[{ + orgId: "INITORG", + status: 2, + url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0" +}, { + orgId: "INITORG", + status: 2, + url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" +}] +``` + +### `quorumPermission_roleList` +Returns the list of roles in the network +#### Parameters +None +#### Returns +* `access`: account access. [refer](#account-access-types) for the complete list of different values of account access. +* `active`: indicates if the role is active or not +* `isAdmin`: indicates if the role is org admin role +* `isVoter`: indicates if the role is enabled for voting. Applicable only for network admin role +* `orgId`: org id to which the role is linked +* `roleId`: unique role id +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_roleList","id":10}' --header "Content-Type: application/json" + +// Response +{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "INITORG", + roleId: "NWADMIN" +} +``` + +```javascript tab="geth console" +> quorumPermission.roleList +[{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "INITORG", + roleId: "NWADMIN" +}] +``` + +### `quorumPermission_getOrgDetails` +This returns the list of accounts, nodes, roles, and sub organizations linked to an organization +#### Parameters +* org or sub org id +#### Returns +* `acctList` +* `nodeList` +* `roleList` +* `subOrgList`: array of sub orgs linked to the org +* Output: list of all accounts, nodes, roles, and sub orgs +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_getOrgDetails","params":["INITORG"],"id":10}' --header "Content-Type: application/json" + +// Response +{ + acctList: [{ + acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 + }, { + acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 + }], + nodeList: [{ + orgId: "INITORG", + status: 2, + url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" + }], + roleList: [{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "INITORG", + roleId: "NWADMIN" + }], + subOrgList: null +} +``` + +```javascript tab="geth console" +> quorumPermission_getOrgDetails("INITORG") +{ + acctList: [{ + acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 + }, { + acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", + isOrgAdmin: true, + orgId: "INITORG", + roleId: "NWADMIN", + status: 2 + }], + nodeList: [{ + orgId: "INITORG", + status: 2, + url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0" + }, { + orgId: "INITORG", + status: 2, + url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" + }], + roleList: [{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "INITORG", + roleId: "NWADMIN" + }], + subOrgList: null +} +``` +### `quorumPermission_addOrg` +This api can be executed by a network admin account (`from:` in transactions args) only for proposing a new organization into the network +#### Parameter +* `orgId`: unique org identfiier +* `enodeId`: complete enode id +* `accountId`: account which will be the org admin account + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_addOrg","params":["ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.addOrg("ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +"Action completed successfully" +``` +If there are any pending items for approval, proposal of any new organization will fail. Also the enode id and accounts can be linked to one organization only. +```javascript tab="geth console" +> quorumPermission.addOrg("ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +Error: Pending approvals for the organization. Approve first + at web3.js:3143:20 + at web3.js:6347:15 + at web3.js:5081:36 + at :1:1 + +> quorumPermission.addOrg("XYZ", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +Error: EnodeId already part of network. + at web3.js:3143:20 + at web3.js:6347:15 + at web3.js:5081:36 + at :1:1 +> quorumPermission.addOrg("XYZ", "enode://de9c2d5937e599930832cecc1df8cc90b50839bdf635c1a4e68e1dab2d001cd4a11c626e155078cc65958a72e2d72c1342a28909775edd99cc39470172cce0ac@127.0.0.1:21004?discport=0", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +Error: Account already in use in another organization + at web3.js:3143:20 + at web3.js:6347:15 + at web3.js:5081:36 + at :1:1 + +``` +### `quorumPermission_approveOrg` +This api can be executed by a network admin account (`from:` in transactions args) only for approving a proposed organization into the network. +#### Parameters +* `orgId`: unique org identfiier +* `enodeId`: complete enode id +* `accountId`: account which will be the org admin account +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_approveOrg","params":["ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +quorumPermission.approveOrg("ABC", "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +"Action completed successfully" +``` +### `quorumPermission_updateOrgStatus` +This api can only be executed by a network admin account and is used for temporarily suspending an organization or re-enabling a suspended organization. This activity can be performed for master organization only and requires majority approval from network admins. +#### Parameters +* `orgId`: org id +* `action`: + * 1 - for suspending a org + * 2 - for activating a suspended organization +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_updateOrgStatus","params":["ABC", 1, {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" +//Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.updateOrgStatus("ABC", 1, {from:eth.accounts[0]}) +"Action completed successfully" +``` + +### `quorumPermission_approveOrgStatus` +This api can only be executed by a network admin account and is used for approving the org status change proposal. Once majority approval is received from network admins, the org status is updated. + +#### Parameters +* `orgId`: org id +* `action`: + * 1 - for approving org suspension + * 2 - for approving activation of suspended org + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_approveOrgStatus","params":["ABC", 1, {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +//Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +quorumPermission.approveOrgStatus("ABC", 1, {from: eth.accounts[0]}) +"Action completed successfully" + +``` + +When an organization is in suspended status, no transactions or contract deploy activities are allowed from any nodes linked to the org and sub organizations under it. Similarly no transactions will be allowed from any accounts linked to the organization + +### `quorumPermission_addSubOrg` +This api can be executed by a organization admin account to create a sub organization under the master org. +#### Parameters +* `parentOrgId`: parent org id under which the sub org is being added. parent org id should contain the complete org hierarchy from master org id to the immediate parent. The org hierarchy is separated by `.`. For example, if master org `ABC` has a sub organization `SUB1`, then while creating the sub organization at `SUB1` level, the parent org should be given as `ABC.SUB1` +* `subOrgId`: sub org identifier +* `enodeId`: complete enode id of the node linked to the sub org id +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_addSubOrg","params":["ABC", "SUB1","", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.addSubOrg("ABC", "SUB1", "", {from: eth.accounts[0]}) +"Action completed successfully" +``` + +Few examples of adding sub org in nested hierarchy: +```javascript +> quorumPermission.addSubOrg("ABC.SUB1", "SUB2","", {from: eth.accounts[0]}) +"Action completed successfully" + +> quorumPermission.addSubOrg("ABC.SUB1.SUB2", "SUB3","", {from: eth.accounts[0]}) +"Action completed successfully" +``` + +### `quorumPermission_addNewRole` +This api can be executed by an organization admin account to create a new role for the organization. + +#### Parameters +* `orgId`: org id for which the role is being created +* `roleId`: unique role identifier +* `accountAccess`: account level access. [Refer](#account-access-types) for complete list +* `isVoter`: `bool` indicates if its a voting role +* `isAdminRole`: `bool` indicates if its an admin role + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_addNewRole","params":["ABC", "TRANSACT",1,false,false, {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.addNewRole("ABC", "TRANSACT", 1, false, false,{from: eth.accounts[0]}) +"Action completed successfully" +> quorumPermission.addNewRole("ABC.SUB1.SUB2.SUB3", "TRANSACT", 1, false, false,{from: eth.accounts[0]}) +"Action completed successfully" +``` + +### `quorumPermission_removeRole` +This api can be executed by an organization admin account to create a new role for the organization. + +#### Parameters +* `orgId`: org or sub org id to which the role belongs +* `roleId`: role id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_removeRole","params":["ABC", "TRANSACT", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.removeRole("ABC.SUB1.SUB2.SUB3", "TRANSACT", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_addAccountToOrg` +This api can be executed by an organization admin to add an account to an organization and assign a role to the account + +#### Parameters +* `acctId`: org or sub org id to which the role belongs +* `orgId`: org id +* `roleId`: role id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_addAccountToOrg","params":["0xf017976fdf1521de2e108e63b423380307f501f8", "ABC", "TRANSACT", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.addAccountToOrg("0xf017976fdf1521de2e108e63b423380307f501f8", "ABC", "TRANSACT", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +The account can at best be linked to a single organization or sub organization and cannot belong to multiple organizations or sub organizations +```javascript +> quorumPermission.addAccountToOrg("0xf017976fdf1521de2e108e63b423380307f501f8", "ABC.SUB1", "TRANSACT", {from: eth.accounts[1]}) +Error: Account already in use in another organization + at web3.js:3143:20 + at web3.js:6347:15 + at web3.js:5081:36 + at :1:1 +``` +### `quorumPermission_changeAccountRole` +This api can be executed by an organization admin account to assign a role to an account. +#### Parameters +* `acctId`: account id +* `orgId`: org id +* `roleId`: new role id to be assigned to the account +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_changeAccountRole","params":["0xf017976fdf1521de2e108e63b423380307f501f8", "ABC", "TRANSACT", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.changeAccountRole("0xf017976fdf1521de2e108e63b423380307f501f8", "ABC", "TRANSACT", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_updateAccountStatus` +This api can be executed by an organization admin account to update the account status. + +#### Parameters +* `orgId`: org id +* `acctId`: org or sub org id to which the role belongs +* `action`: + * 1 - for suspending the account + * 2 - for activating a suspended account + * 3 - for blacklisting an account + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_updateAccountStatus","params":["ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", 1, {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.updateAccountStatus("ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", 1, {from: eth.accounts[1]}) +"Action completed successfully" +``` + +Once a account is blacklisted it can only be recovered by network admins. Refer to [quorumPermission_recoverBlackListedAccount](#quorumpermission_recoverblacklistedaccount) and [quorumPermission_approveBlackListedAccountRecovery](#quorumpermission_approveblacklistedaccountrecovery) for further details. + +### `quorumPermission_recoverBlackListedAccount` +This api can be executed by the network admin account to initiate the recovery of a blacklisted account. Post majority approval from network admin accounts, the blacklisted account will be marked as active. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `acctId`: blacklisted account id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_recoverBlackListedAccount","params":["ABC.SUB1.SUB2.SUB3", "0xf017976fdf1521de2e108e63b423380307f501f8", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.recoverBlackListedAccount("ABC.SUB1.SUB2.SUB3", "0xf017976fdf1521de2e108e63b423380307f501f8", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_approveBlackListedAccountRecovery` +This api can be executed by the network admin approve the recovery of a blacklisted account. Once majority approvals from network admin accounts is received, the account is marked as active. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `acctId`: blacklisted account id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_approveBlackListedNodeRecovery","params":["ABC.SUB1.SUB2.SUB3", "0xf017976fdf1521de2e108e63b423380307f501f8", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.approveBlackListedNodeRecovery("ABC.SUB1.SUB2.SUB3", "0xf017976fdf1521de2e108e63b423380307f501f8", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_assignAdminRole` +This api can be executed by the network admin to add a new account as network admin or change the org admin account for an organization. + +#### Parameters +* `orgId`: org id to which the account belongs +* `acctId`: account id +* `roleId`: new role id to be assigned to the account. This can be the network admin role or org admin role only + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_assignAdminRole","params":["ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", "NWADMIN", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.assignAdminRole("ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", "NWADMIN", {from: eth.accounts[0]}) +"Action completed successfully" +``` + +### `quorumPermission_approveAdminRole` +This api can be executed by the network admin to approve the organization admin or network admin role assignment to an account. The role is approved once majority approval is received. + +#### Parameters +* `orgId`: org id to which the account belongs +* `acctId`: account id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_approveAdminRole","params":["ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.approveAdminRole("ABC", "0xf017976fdf1521de2e108e63b423380307f501f8", {from: eth.accounts[0]}) +"Action completed successfully" +``` + +### `quorumPermission_addNode` +This api can be executed by the organization admin account to add a node to the organization or sub organization. A node cannot be part of multiple organizations. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `enodeId`: complete enode id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_addNode","params":["ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.addNode("ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_updateNodeStatus` +This api can be executed by the organization admin account to update the status of a node. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `enodeId`: complete enode id +* `action`: + * 1 - for deactivating the node + * 2 - for activating a deactivated node + * 3 - for blacklisting a node + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_updateNodeStatus","params":["ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407",1, {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.updateNodeStatus("ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407",3, {from: eth.accounts[1]}) +"Action completed successfully" +``` + +Once a node is blacklisted it can only be recovered by network admins. Refer to [quorumPermission_recoverBlackListedNode](#quorumpermission_recoverblacklistednode) and [quorumPermission_approveBlackListedNodeRecovery](#quorumpermission_approveblacklistednoderecovery) for further details. + +### `quorumPermission_recoverBlackListedNode` +This api can be executed by the network admin account to initiate the recovery of a blacklisted node. Post majority approval from network admin accounts, the blacklisted node will be marked as active. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `enodeId`: complete enode id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_recoverBlackListedNode","params":["ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.recoverBlackListedNode("ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +### `quorumPermission_approveBlackListedNodeRecovery` +This api can be executed by the network admin approve the recovery of a blacklisted node. Once majority approvals from network admin accounts is received, the node is marked as active. + +#### Parameters +* `orgId`: org or sub org id to which the node belongs +* `enodeId`: complete enode id + +#### Returns +* `msg`: response message +* `status`: `bool` indicating if the operation was success or failure + +#### Examples + +```jshelllanguage tab="JSON RPC" +// Request +curl -X POST http://127.0.0.1:22000 --data '{"jsonrpc":"2.0","method":"quorumPermission_approveBlackListedNodeRecovery","params":["ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {"from":"0xed9d02e382b34818e88b88a309c7fe71e65f419d"}],"id":10}' --header "Content-Type: application/json" + +// Response +{"jsonrpc":"2.0","id":10,"result":"Action completed successfully"} +``` + +```javascript tab="geth console" +> quorumPermission.approveBlackListedNodeRecovery("ABC.SUB1.SUB2.SUB3", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0&raftport=50407", {from: eth.accounts[1]}) +"Action completed successfully" +``` + +## Roles +The table below indicates the numeric value for each account access type. + +| AccessType | Value | +|:--------------:|:-----:| +| ReadOnly | 0 | +| Transact | 1 | +| ContractDeploy | 2 | +| FullAccess | 3 | + +When setting the account access, the system checks if the account setting the access has sufficient privileges to perform the activity. + +* Accounts with `FullAccess` can grant any access type (`FullAccess`, `Transact`, `ContractDeploy` or `ReadOnly`) to any other account +* Accounts with `ContractDeploy` can grant only `Transact`, `ContractDeploy` or `ReadOnly` access to other accounts +* Accounts with `Transact` access can grant only `Transact` or `ReadOnly` access to other accounts +* Accounts with `ReadOnly` access cannot grant any access + +## Status Mapping +### Organization status types +The table below indicates the numeric value for various organization status. + +| OrgStatus | Value | +| :-----------------------: | :-------------: | +| NotInList | 0 | +| Proposed | 1 | +| Approved | 2 | +| PendingSuspension | 3 | +| Suspended | 4 | +| AwaitingSuspensionRevoke | 5 | + +### Account status types +The table below indicates the numeric value for various account status. + +| AccountStatus | Value | +| :-------------: | :-------------: | +| Not In List | 0 | +| Pending Approval | 1 | +| Active | 2 | +| Inactive | 3 | +| Suspended | 4 | +| Blacklisted | 5 | +| Revoked | 6 | +| Recovery initiated for Blacklisted accounts | 7 | + +### Node Status types +The table below indicates the numeric value for various node status. + +| NodeStatus | Value | +| :-----------------------: | :-------------: | +| NotInList | 0 | +| PendingApproval | 1 | +| Approved | 2 | +| Deactivated | 3 | +| Blacklisted | 4 | +| Recovery initiated for Blacklisted Node | 5 | \ No newline at end of file diff --git a/docs/Permissioning/Usage.md b/docs/Permissioning/Usage.md new file mode 100644 index 0000000000..daf0cf09b7 --- /dev/null +++ b/docs/Permissioning/Usage.md @@ -0,0 +1,504 @@ + +**This section describes the usage of permission model for creation of a network, initial set up and management of network. The network management activities can be broadly categorized into:** + +* [Initial network set up](#initial-network-set-up) +* [Proposing a new organization into the network](#proposing-a-new-organization-into-the-network) +* [Organization admin managing the organization level permissions](#organization-admin-managing-the-organization-level-permissions) +* [Suspending an organization temporarily](#suspending-an-organization-temporarily) +* [Revoking suspension of an organization](#revoking-suspension-of-an-organization) +* [Assigning admin privileges at organization and network level](#assigning-admin-privileges-at-organization-and-network-level) + + +### Initial network set up +Please refer to [set up](../setup). For an existing network running with an older version of Quorum: + +* Upgrade Quorum to the latest version +* Deploy the contracts +* Execute the `init` method of `PermissionsUpgradable.sol` from the guardian account +* Copy the `permission-config.json` to the data directory of each node +* Bring `geth` up in `--permissioned` mode. + +For a new network using the latest version of Quorum: + +* Bring up the initial set of nodes +* Deploy the contracts +* Execute the `init` method of `PermissionsUpgradable.sol` from the guardian account +* Upgrade Quorum to the latest version +* Copy the `permission-config.json` to the data directory of each node +* Bring `geth` up in `--permissioned` mode. + +As part of network initialization: + +* A network admin organization is created with the `nwAdminOrg` name specified in `permission-config.json`. All nodes which are part of `static-nodes.json` are assigned to this organization. +* A network admin role is created with the `nwAdminRole` name specified in the config file. +* All accounts given in the `accounts` array of the config file are assigned the network admin role. These accounts will have the ability to propose and approve new organizations into the network. + +Assuming that the network was started with the `permission-config.json` given in the [set up](../setup), and assuming the network was brought up with the `static-nodes.json` file given below: +```json +[ + "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0", + "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0", + "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0", + "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" +] +``` +then the network will have the following configuration once it has started up: +``` +> quorumPermission.orgList +[{ + fullOrgId: "ADMINORG", + level: 1, + orgId: "ADMINORG", + parentOrgId: "", + status: 2, + subOrgList: null, + ultimateParent: "ADMINORG" +}] +> quorumPermission.getOrgDetails("ADMINORG") +{ + acctList: [{ + acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", + isOrgAdmin: true, + orgId: "ADMINORG", + roleId: "ADMIN", + status: 2 + }, { + acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", + isOrgAdmin: true, + orgId: "ADMINORG", + roleId: "ADMIN", + status: 2 + }], + nodeList: [{ + orgId: "ADMINORG", + status: 2, + url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0" + }, { + orgId: "ADMINORG", + status: 2, + url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0" + }, { + orgId: "ADMINORG", + status: 2, + url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0" + }, { + orgId: "ADMINORG", + status: 2, + url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0" + }], + roleList: [{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "ADMINORG", + roleId: "ADMIN" + }], + subOrgList: null +} +``` + +### Proposing a new organization into the network +Once the network is up, the network admin accounts can then propose a new organization into the network. Majority approval from the network admin accounts is required before an organization is approved. The APIs for [proposing](../Permissioning%20apis#quorumpermissionaddorg) and [approving](../Permissioning%20apis#quorumpermissionapproveorg) an organization are documented in [permission APIs](../Permissioning%20apis) + +#### Example +An example to propose and approve an organization by name `ORG1` is as shown below: + +```javascript +> quorumPermission.addOrg("ORG1", "enode://de9c2d5937e599930832cecc1df8cc90b50839bdf635c1a4e68e1dab2d001cd4a11c626e155078cc65958a72e2d72c1342a28909775edd99cc39470172cce0ac@127.0.0.1:21004?discport=0", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) +"Action completed successfully" +``` + +Once the org is proposed, it will be in `Proposed` state awaiting approval from other network admin accounts. The org status is as shown below: +```javascript +> quorumPermission.orgList[1] +{ + fullOrgId: "ORG1", + level: 1, + orgId: "ORG1", + parentOrgId: "", + status: 1, + subOrgList: null, + ultimateParent: "ORG1" +} +``` + +The network admin accounts can then approve the proposed organizations and once the majority approval is achieved, the organization status is updated as `Approved` + +```javascript +> quorumPermission.approveOrg("ORG1", "enode://de9c2d5937e599930832cecc1df8cc90b50839bdf635c1a4e68e1dab2d001cd4a11c626e155078cc65958a72e2d72c1342a28909775edd99cc39470172cce0ac@127.0.0.1:21004?discport=0", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e"}) +"Action completed successfully" +> quorumPermission.orgList[1] +{ + fullOrgId: "ORG1", + level: 1, + orgId: "ORG1", + parentOrgId: "", + status: 2, + subOrgList: null, + ultimateParent: "ORG1" +} +``` + +The details of the new organization approved are as below: +```javascript +> quorumPermission.getOrgDetails("ORG1") +{ + acctList: [{ + acctId: "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", + isOrgAdmin: true, + orgId: "ORG1", + roleId: "ORGADMIN", + status: 2 + }], + nodeList: [{ + orgId: "ORG1", + status: 2, + url: "enode://de9c2d5937e599930832cecc1df8cc90b50839bdf635c1a4e68e1dab2d001cd4a11c626e155078cc65958a72e2d72c1342a28909775edd99cc39470172cce0ac@127.0.0.1:21004?discport=0" + }], + roleList: [{ + access: 3, + active: true, + isAdmin: true, + isVoter: true, + orgId: "ORG1", + roleId: "ORGADMIN" + }], + subOrgList: null +} +``` + +As can be seen from the above, as a part of approval: + +* A org admin role with name as given in `orgAdminRole` in `permission-config.json` has been created and linked to the organization `ORG1` +* The account given has been linked to the organization `ORG1` and org admin role. This account acts as the organization admin account and can in turn manage further roles, nodes and accounts at organization level +* The node has been linked to organization and status has been updated as `Approved` + +The new node belonging to the organization can now join the network. In case the network is running in `Raft` consensus mode, before the node joins the network, please ensure that: + +* The node has been added as a peer using `raft.addPeer(<>)` +* Bring up `geth` for the new node using `--raftjoinexisting` with the peer id as obtained in the above step + +### Organization admin managing the organization level permissions +Once the organization is approved and the node of the organization has joined the network, the organization admin can then create sub organizations, roles, add additional nodes at organization level, add accounts to the organization and change roles of existing organization level accounts. + +To add a sub org at `ORG1` level refer to [addSubOrg API](../Permissioning%20apis#quorumpermissionaddsuborg) +```javascript +> quorumPermission.addSubOrg("ORG1", "SUB1", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0", {from: eth.accounts[0]}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1") +{ + acctList: null, + nodeList: [{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" + }], + roleList: null, + subOrgList: null +} +``` + +For adding a sub org the enode id is not mandatory. For the newly created sub org if the org admin desires to add an administration account, the org admin account will have to first create a role with `isAdmin` flag as `Y` and then assign this role to the account which belongs to the sub org. Once assigned the account will act as org admin at sub org level. Refer to [addNewRole API](../Permissioning%20apis#quorumpermissionaddnewrole) +```javascript +> quorumPermission.addNewRole("ORG1.SUB1", "SUBADMIN", 3, false, true,{from: eth.accounts[0]}) +"Action completed successfully" +> eth.accounts[0] +"0x0638e1574728b6d862dd5d3a3e0942c3be47d996" +``` + +The role `SUBADMIN` can now be assigned to an account at sub org `SUB1` for making the account admin for the sub org. +```javascript +> quorumPermission.addAccountToOrg("0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", "ORG1.SUB1", "SUBADMIN", {from: "0x0638e1574728b6d862dd5d3a3e0942c3be47d996"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1") +{ + acctList: [{ + acctId: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN", + status: 2 + }], + nodeList: [{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" + }], + roleList: [{ + access: 3, + active: true, + isAdmin: true, + isVoter: false, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN" + }], + subOrgList: null +} +``` + +The account `0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0` is now the admin for sub org `SUB1` and will be able to add roles, accounts and nodes to the sub org. It should be noted that the org admin account at master org level has the admin rights on all the sub organizations below. However the admin account at sub org level has control only in the sub org to which it is linked. +```javascript +> quorumPermission.addNewRole("ORG1.SUB1", "TRANSACT", 1, false, true,{from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").roleList +[{ + access: 3, + active: true, + isAdmin: true, + isVoter: false, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN" +}, { + access: 1, + active: true, + isAdmin: true, + isVoter: false, + orgId: "ORG1.SUB1", + roleId: "TRANSACT" +}] +``` + +To add an account to an organization refer to [addAccountToOrg API](../Permissioning%20apis#quorumpermissionaddaccounttoorg). +```javascript +> quorumPermission.addAccountToOrg("0x283f3b8989ec20df621166973c93b56b0f4b5455", "ORG1.SUB1", "SUBADMIN", {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").acctList + +[{ + acctId: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN", + status: 2 +}, { + acctId: "0x283f3b8989ec20df621166973c93b56b0f4b5455", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "TRANSACT", + status: 2 +}] +``` + +To suspend an account [updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 1. +```javascript +> quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 1, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").acctList +[{ + acctId: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN", + status: 2 +}, { + acctId: "0x283f3b8989ec20df621166973c93b56b0f4b5455", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "TRANSACT", + status: 1 +}] +``` + +To revoke suspension of an account [updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 2. +```javascript +> quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 2, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").acctList + +[{ + acctId: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN", + status: 2 +}, { + acctId: "0x283f3b8989ec20df621166973c93b56b0f4b5455", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "TRANSACT", + status: 2 +}] +``` + +To [blacklist an account updateAccountStatus](../Permissioning%20apis#quorumpermissionupdateaccountstatus) API can be invoked with action as 3. Once blacklisted no further activity will be possible on the account. +```javascript +> quorumPermission.updateAccountStatus("ORG1.SUB1", "0x283f3b8989ec20df621166973c93b56b0f4b5455", 3, {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").acctList + +[{ + acctId: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "SUBADMIN", + status: 2 +}, { + acctId: "0x283f3b8989ec20df621166973c93b56b0f4b5455", + isOrgAdmin: true, + orgId: "ORG1.SUB1", + roleId: "TRANSACT", + status: 5 +}] +``` + +To [add nodes addNode ](../Permissioning%20apis#quorumpermissionaddnode) at organization and sub organization level by the org admin. +```javascript +> quorumPermission.addNode("ORG1.SUB1", "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0", {from: "0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").nodeList +[{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" +}, { + orgId: "ORG1.SUB1", + status: 2, + url: "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0" +}] +``` + +Org admin can manage the status of the nodes by using [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API. To deactivate a node the API can be invoked with action 1. +```javascript +> quorumPermission.getOrgDetails("ORG1.SUB1").nodeList +[{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" +}, { + orgId: "ORG1.SUB1", + status: 3, + url: "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0" +}] +``` + +To activate the node back invoke [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API with action 2. +```javascript +> quorumPermission.updateNodeStatus("ORG1.SUB1", "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0",2, {from:"0x42ef6abedcb7ecd3e9c4816cd5f5a96df35bb9a0"}) +"Action completed successfully" +> quorumPermission.getOrgDetails("ORG1.SUB1").nodeList +[{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" +}, { + orgId: "ORG1.SUB1", + status: 2, + url: "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0" +}] +``` + +To blacklist a node invoke [updateNodeStatus](../Permissioning%20apis#quorumpermissionupdatenodestatus) API with action 3. Once blacklisted the node will never be able join the network again. +```javascript +> quorumPermission.getOrgDetails("ORG1.SUB1").nodeList +[{ + orgId: "ORG1.SUB1", + status: 2, + url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0" +}, { + orgId: "ORG1.SUB1", + status: 4, + url: "enode://eacaa74c4b0e7a9e12d2fe5fee6595eda841d6d992c35dbbcc50fcee4aa86dfbbdeff7dc7e72c2305d5a62257f82737a8cffc80474c15c611c037f52db1a3a7b@127.0.0.1:21005?discport=0" +}] +``` + +It should be noted that in the case of the `Raft` consensus mechanism, when the node is deactivated the peer id is lost and hence upon activation, the node needs to be added to Raft cluster again using `raft.addPeer` and the node should be brought up with new peer id. + +Further: + +* An account can transact from any of the nodes linked to org or sub org with in the same organization +* If a node is deactivated no transaction will be allowed from that node + +### Suspending an organization temporarily +If there is a need to temporarily suspend all activities of an organization [updateOrgStatus](../Permissioning%20apis#quorumpermissionupdateorgstatus) API can be invoked with action 1. This can be invoked only by the network admin accounts and will reuiqre majority voting. +```javascript +> quorumPermission.updateOrgStatus("ORG1", 1, {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) +"Action completed successfully" +> quorumPermission.orgList[2] +{ + fullOrgId: "ORG1", + level: 1, + orgId: "ORG1", + parentOrgId: "", + status: 3, + subOrgList: null, + ultimateParent: "ORG1" +} +``` + +To approve the org, suspension majority approval from other network admin accounts is required. The api for the same is [approveOrgStatus](../Permissioning%20apis#quorumpermissionapproveorgstatus). Once approved the org status is marked as suspended. +```javascript +> quorumPermission.approveOrgStatus("ORG1", 1, {from: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e"}) +"Action completed successfully" +> quorumPermission.orgList[2] +{ + fullOrgId: "ORG1", + level: 1, + orgId: "ORG1", + parentOrgId: "", + status: 4, + subOrgList: null, + ultimateParent: "ORG1" +} +``` + +When the org is suspended no transaction from any of the account linked to the organization or sub organizations under it is allowed. However, the nodes linked to the organization will be active and will be syncing with the network. + + +### Revoking suspension of an organization +To revoke the suspension of an org [updateOrgStatus](../Permissioning%20apis#quorumpermissionupdateorgstatus) can be called with action as 2. This will require majority approval (API [approveOrgStatus](../Permissioning%20apis#quorumpermissionapproveorgstatus) with action 2). +```javascript +> quorumPermission.updateOrgStatus("ORG1", 2, {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) +"Action completed successfully" +> quorumPermission.approveOrgStatus("ORG1", 2, {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) +"Action completed successfully" +> quorumPermission.orgList[0] +{ + fullOrgId: "ORG1.SUB1", + level: 2, + orgId: "SUB1", + parentOrgId: "ORG1", + status: 2, + subOrgList: null, + ultimateParent: "ORG1" +} +``` + +Once the revoke is approved, all accounts in the organization and sub organization will be able to transact as per role level access. + +### Assigning admin privileges at organization and network level +There may be a scenario where one of the accounts at the organization level needs to have network admin level permissions and be able to perform network admin activities. Similarly there can be a need to change the admin account at organization level. Both these activities can be performed by existing network admin accounts only, and will require majority approval from the network admin accounts. The API usage details are as below. +To assign network admin or org admin role to an account invoke [assignAdminRole](../Permissioning%20apis#quorumpermissionassignadminrole). +```javascript +> quorumPermission.assignAdminRole("ORG1", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", "ADMIN", {from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"}) +"Action completed successfully" +> quorumPermission.acctList[3] +{ + acctId: "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", + isOrgAdmin: true, + orgId: "ORG1", + roleId: "ADMIN", + status: 1 +} +``` + +To approve the assignment of network admin role invoke [approveAdminRole](../Permissioning%20apis#quorumpermissionapproveadminrole) API. +```javascript +> quorumPermission.approveAdminRole("ORG1", "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", {from: eth.accounts[0]}) +"Action completed successfully" +> quorumPermission.acctList[4] +{ + acctId: "0x0638e1574728b6d862dd5d3a3e0942c3be47d996", + isOrgAdmin: true, + orgId: "ORG1", + roleId: "ADMIN", + status: 2 +} +``` + +The above account can now perform all activities allowable by a network admin account and can participate in the approval process for any actions at network level. + + + + + diff --git a/docs/Permissioning/images/ContractDesign.png b/docs/Permissioning/images/ContractDesign.png new file mode 100644 index 0000000000..134b888791 Binary files /dev/null and b/docs/Permissioning/images/ContractDesign.png differ diff --git a/docs/Permissioning/images/PermissionsModel.png b/docs/Permissioning/images/PermissionsModel.png new file mode 100644 index 0000000000..935b10cb7e Binary files /dev/null and b/docs/Permissioning/images/PermissionsModel.png differ diff --git a/docs/Permissioning/images/sampleNetwork.png b/docs/Permissioning/images/sampleNetwork.png new file mode 100644 index 0000000000..07a49fc4cb Binary files /dev/null and b/docs/Permissioning/images/sampleNetwork.png differ diff --git a/docs/Permissioning/setup.md b/docs/Permissioning/setup.md new file mode 100644 index 0000000000..215b29bfcf --- /dev/null +++ b/docs/Permissioning/setup.md @@ -0,0 +1,77 @@ +# Set up +The steps to enable new permissions model are as described below: + +## New network + +* Bring up the initial set of nodes which will be part of the network +* Deploy the `PermissionsUpgradable.sol` in the network. The deployment of this contract will require a guardian account to be given as a part of deployment. +* Deploy the rest of the contracts. All the other contracts will require the address of `PermissionsUpgradable.sol` contract as a part of deployment. +* Once all the contracts are deployed create a file `permission-config.json` which will have the following construct: +```json +{ + "upgradableAddress": "0x1932c48b2bf8102ba33b4a6b545c32236e342f34", + "interfaceAddress": "0x4d3bfd7821e237ffe84209d8e638f9f309865b87", + "implAddress": "0xfe0602d820f42800e3ef3f89e1c39cd15f78d283", + "nodeMgrAddress": "0x8a5e2a6343108babed07899510fb42297938d41f", + "accountMgrAddress": "0x9d13c6d3afe1721beef56b55d303b09e021e27ab", + "roleMgrAddress": "0x1349f3e1b8d71effb47b840594ff27da7e603d17", + "voterMgrAddress": "0xd9d64b7dc034fafdba5dc2902875a67b5d586420", + "orgMgrAddress" : "0x938781b9796aea6376e40ca158f67fa89d5d8a18", + "nwAdminOrg": "ADMINORG", + "nwAdminRole" : "ADMIN", + "orgAdminRole" : "ORGADMIN", + "accounts":["0xed9d02e382b34818e88b88a309c7fe71e65f419d", "0xca843569e3427144cead5e4d5999a3d0ccf92b8e"], + "subOrgBreadth" : 3, + "subOrgDepth" : 4 +} +``` +> * `upgradableAddress` is the address of deployed contract `PermissionsUpgradable.sol` +> * `interfaceAddress` is the address of deployed contract `PermissionsInterface.sol` +> * `implAddress` is the address of deployed contract `PermissionsImplementation.sol` +> * `nodeMgrAddress` is the address of deployed contract `NodeManager.sol` +> * `accountMgrAddress` is the address of deployed contract `AccountManager.sol` +> * `roleMgrAddress` is the address of deployed contract `RoleManager.sol` +> * `voterMgrAddress` is the address of deployed contract `VoterManager.sol` +> * `orgMgrAddress` is the address of deployed contract `OrgManager.sol` +> * `nwAdminOrg` is the name of initial organization that will be created as a part of network boot up with new permissions model. This organization will own all the initial nodes which come at the time of network boot up and accounts which will be the network admin account +> * `nwAdminRole` is role id which will have full access and will be network admin. This role will be assigned to the network admin accounts +> * `orgAdminRole` is role id which will have full access and will manage organization level administration activities. This role will be assigned to the org admin account +> * `accounts` holds the initial list of accounts which will be linked to the network admin organization and will be assigned the network admin role. These accounts will have complete control on the network and can propose and approve new organizations into the network +> * `subOrgBreadth` indicates the number of sub organizations that any org can have +> * `subOrgDepth` indicates the maximum depth of sub org hierarchy allowed in the network + +* Once the contracts are deployed, `init` in `PermissionsUpgradable.sol` need to be executed by the guardian account. This will link the interface and implementation contracts. A sample script for loading the upgradable contract at `geth` prompt is as given below +```javascript +ac = eth.accounts[0]; +web3.eth.defaultAccount = ac; +var abi = [{"constant":true,"inputs":[],"name":"getPermImpl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_proposedImpl","type":"address"}],"name":"confirmImplChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getGuardian","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPermInterface","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_permInterface","type":"address"},{"name":"_permImpl","type":"address"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_guardian","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]; +var upgr = web3.eth.contract(abi).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); // address of the upgradable contracts +var impl = "0xfe0602d820f42800e3ef3f89e1c39cd15f78d283" // address of the implementation contracts +var intr = "0x4d3bfd7821e237ffe84209d8e638f9f309865b87" // address of the interface contracts +``` +* At `geth` prompt load the above script after replacing the contract addresses appropriately and execute `upgr.init(intr, impl, {from: , gas: 4500000})` +* Bring down the all `geth` nodes in the network and copy `permission-config.json` into the data directory of each node + +## Migrating from an earlier version +The following steps needs to be followed when migrating from a earlier version for enabling permissions feature + +* Bring down the running network in the earlier version. +* The `maxCodeSize` attribute in `genesis.json` need to be set to 35. Update `genesis.json` to reflect the same +```javascript + "config": { + "homesteadBlock": 0, + "byzantiumBlock": 0, + "chainId": 10, + "eip150Block": 0, + "eip155Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip158Block": 0, + "maxCodeSize" : 35, + "isQuorum": +``` +* Execute `geth --datadir <> init genesis.json` +* Bring up the network with latest geth and deploy the contracts as explained earlier in the set up. The rest of the steps will be similar to bringing up a new network + +!!! Note + * It should be noted that the new permission model will be in force only when `permission-config.json` is present in data directory. If this file is not there and the node is brought up with `--permissioned` flag, node level permissions as per the earlier model will be effective. + * Please ensure that `maxCodeSize` in `genesis.json` is set to 35 diff --git a/docs/Privacy/Tessera/Configuration/Configuration Overview.md b/docs/Privacy/Tessera/Configuration/Configuration Overview.md index 12d60a0db3..63660addb9 100644 --- a/docs/Privacy/Tessera/Configuration/Configuration Overview.md +++ b/docs/Privacy/Tessera/Configuration/Configuration Overview.md @@ -29,6 +29,54 @@ Tessera's database uses JDBC to connect to an external database. Any valid JDBC } ``` +#### Obfuscate database password in config file + +Certain entries in the Tessera config file must be obfuscated in order to prevent any attempts from attackers to gain access to critical parts of the application (e.g. database). The database password can be encrypted using [Jasypt](http://www.jasypt.org) to avoid it being exposed as plain text in the configuration file. + +To enable this feature, simply replace your plain-text database password with its encrypted value and wrap it inside an `ENC()` function. + +```json +"jdbc": { + "username": "sa", + "password": "ENC(ujMeokIQ9UFHSuBYetfRjQTpZASgaua3)", + "url": "jdbc:h2:/qdata/c1/db1", + "autoCreateTables": true +} +``` + +Being a Password-Based Encryptor, Jasypt requires a secret key (password) and a configured algorithm to encrypt/decrypt this config entry. This password can either be loaded into Tessera from file system or user input. For file system input, the location of this secret file needs to be set in Environment Variable `TESSERA_CONFIG_SECRET` + +If the database password is not wrapped inside `ENC()`, Tessera will simply treat it as a plain-text password however this approach is not recommended for production environments. + +!!! note + Jasypt encryption is currently only available for the `jdbc.password` field + +##### How to encrypt database password + +1. Download and unzip [Jasypt](http://www.jasypt.org) and redirect to the `bin` directory +1. Encrypt the password + ``` bash + $ ./encrypt.sh input=dbpassword password=quorum + + ----ENVIRONMENT----------------- + + Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.171-b11 + + + + ----ARGUMENTS------------------- + + input: dbpassword + password: quorum + + + + ----OUTPUT---------------------- + + rJ70hNidkrpkTwHoVn2sGSp3h3uBWxjb + ``` +1. Place the wrapped output, `ENC(rJ70hNidkrpkTwHoVn2sGSp3h3uBWxjb)`, in the config json file + --- ### Server @@ -59,7 +107,7 @@ HTTP: { "app": "", "enabled": , - "serverUri":"http://[host]:[port]/[path] + "serverAddress":"http://[host]:[port]/[path] "communicationType" : , // "REST" or "GRPC" } ``` @@ -68,7 +116,7 @@ HTTPS: { "app": "", "enabled": , - "serverUri":"https://[host]:[port]/[path] + "serverAddress":"https://[host]:[port]/[path] "communicationType" : , // "REST" or "GRPC" "sslConfig": { ...... @@ -80,7 +128,7 @@ Unix Socket: { "app": "", "enabled": , - "serverUri":"unix://[path], + "serverAddress":"unix://[path], "communicationType" : "REST" } ``` @@ -135,6 +183,29 @@ Unix Socket: ### TLS/SSL: server sub-config See [TLS/SSL](../TLS) page. +### CORS: server sub-config +For the ThirdParty server type it may be relevant to configure CORS. +``` +{ + "app":"ThirdParty", + "enabled": true, + "serverAddress": "http://localhost:9081", + "communicationType" : "REST", + "cors" : { + "allowedMethods" : ["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"], + "allowedOrigins" : ["http://localhost:63342"], + "allowedHeaders" : ["content-type"], + "allowCredentials" : true + } +}, +``` +The configurable fields are: + +* `allowedMethods` - the list of allowed HTTP methods. If omitted the default list containing `"GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"` is used. +* `allowedOrigins` - the list of domains from which to accept cross origin requests (browser enforced). Each entry in the list can contain the "*" (wildcard) character which matches any sequence of characters. Ex: "*locahost" would match "http://localhost" or "https://localhost". There is no default for this field. +* `allowedHeaders` - the list of allowed headers. If omitted the request `Access-Control-Request-Headers` are copied into the response as `Access-Control-Allow-Headers`. +* `allowCredentials` - the value for the `Access-Control-Allow-Credentials` response header. If omitted the default `true` value would be used. + ### InfluxDB Config: server sub-config Configuration details to allow Tessera to record monitoring data to a running InfluxDB instance. ``` @@ -181,3 +252,50 @@ 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 + } +``` + +--- + +### Encryptor - Supporting alternative curves in Tessera + +By default Tessera uses the [NaCl(salt)](https://nacl.cr.yp.to/) library in order to encrypt private payloads (which uses a particular combination of Curve25519, Salsa20, and Poly1305 under the hood). + +Alternative curves/symmetric ciphers can be used by configuring the EC Encryptor (which relies on JCA to perform a similar logic to NaCl). + +This is a feature introduced in Tessera v0.10.2. Providing no `encryptor` configuration results in the standard pre-v0.10.2 Tessera behaviour. + +``` +"encryptor": { + "type":"EC", + "properties":{ + "symmetricCipher":"AES/GCM/NoPadding", + "ellipticCurve":"secp256r1", + "nonceLength":"24", + "sharedKeyLength":"32" + } +} +``` + +Field|Default Value|Description +-------------|-------------|----------- +`type`|`NACL`|The encryptor type. Possible values are `EC` or `NACL`. + +If `type` is set to `EC`, the following `properties` fields can also be configured: + +Field|Default Value|Description +-------------|-------------|----------- +`ellipticCurve`|`secp256r1`|The elliptic curve to use. See [SunEC provider](https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunEC) for other options. Depending on the JCE provider you are using there may be additional curves available. +`symmetricCipher`|`AES/GCM/NoPadding`|The symmetric cipher to use for encrypting data (GCM IS MANDATORY as an initialisation vector is supplied during encryption). +`nonceLength`|`24`|The nonce length (used as the initialization vector - IV - for symmetric encryption). +`sharedKeyLength`|`32`|The key length used for symmetric encryption (keep in mind the key derivation operation always produces 32 byte keys - so the encryption algorithm must support it). + +--- diff --git a/docs/Privacy/Tessera/Configuration/Keys.md b/docs/Privacy/Tessera/Configuration/Keys.md index f91cf5d0e7..38cb0f42bd 100644 --- a/docs/Privacy/Tessera/Configuration/Keys.md +++ b/docs/Privacy/Tessera/Configuration/Keys.md @@ -1,7 +1,12 @@ +!!! warning "Change from Tessera v0.10.2+" + The `keys.keyData.passwords` field is no longer supported as of Tessera v0.10.2. + + Instead, use `keys.keyData.passwordFile` or utilise the [CLI password prompt](#providing-key-passwords-at-runtime) when starting the node. + Tessera uses cryptographic keys to provide transaction privacy. You can use existing private/public key pairs as well as use Tessera to generate new key pairs for you. See [Generating & securing keys](../../Tessera%20Services/Keys/Keys) for more info. -``` +```json "keys": { "passwords": [], "passwordFile": "Path", @@ -16,7 +21,7 @@ You can use existing private/public key pairs as well as use Tessera to generate }, "keyData": [ { - //The data for a private/public key pair + // The data for a private/public key pair } ] } @@ -25,11 +30,14 @@ You can use existing private/public key pairs as well as use Tessera to generate ## KeyData Key pairs can be provided in several ways: -#### 1. Direct key pairs -Direct key pairs are convenient but are the least secure configuration option available, as you expose your private key in the configuration file. More secure options are available and preferable for production environments. +### Direct key pairs -The key pair data is provided in plain text in the configfile: -``` +!!! warning + Direct key pairs and unprotected inline key pairs are convenient but are the least secure configuration options available as the private key is exposed in the configuration file. The other options available are more secure and recommended for production environments. + +The key pair data is provided in plain text in the configfile. + +```json "keys": { "keyData": [ { @@ -40,9 +48,14 @@ The key pair data is provided in plain text in the configfile: } ``` -#### 2. Inline key pairs -The public key is provided in plain text. The private key is provided through additional config: -``` +### Inline key pairs +#### Unprotected + +!!! warning + Direct key pairs and unprotected inline key pairs are convenient but are the least secure configuration options available as the private key is exposed in the configuration file. The other options available are more secure and recommended for production environments. + +The key pair data is provided in plain text in the configfile. The plain text private key is provided in a `config` json object: +```json "keys": { "keyData": [ { @@ -58,11 +71,13 @@ The public key is provided in plain text. The private key is provided through a } ``` -This allows for the use of Argon2 password-secured private keys by including the corresponding Argon2 settings in the additional config: +#### Protected +The public key is provided in plain text. The private key must be password-protected using Argon2. The corresponding encrypted data is provided in the `config` json object. -``` +```json "keys": { "passwords": ["password"], + "passwordFile": "/path/to/pwds.txt", "keyData": [ { "config": { @@ -85,9 +100,73 @@ This allows for the use of Argon2 password-secured private keys by including the } ``` -#### 3. Azure Key Vault key pairs -The keys in the pair are stored as secrets in an Azure Key Vault. This requires providing the vault url and the secret IDs for both keys: +Passwords must be provided so that Tessera can decrypt and use the private keys. Passwords can be provided in multiple ways: + +| | Description | +|--------|--------------| +| File | `"passwordFile": "/path/to/pwds.txt"`
Must contain only one password per line. Empty lines should be used for unlocked keys. Passwords must be provided in the order that key pairs are defined in the config. | +| Direct | `"passwords": ["pwd1", "pwd2", ...]`
Empty strings should be used for unlocked keys. Passwords must be provided in the order that key pairs are defined in the config. Not recommended for production use. | +| CLI | Tessera will prompt on the CLI for the passwords of any encrypted keys that have not had passwords provided in the config. This process only needs to be performed once, when starting the node. | + +### Filesystem key pairs +The keys in the pair are stored in files: +```json +"keys": { + "passwords": ["password"], + "passwordFile": "/path/to/pwds.txt", + "keyData": [ + { + "privateKeyPath": "/path/to/privateKey.key", + "publicKeyPath": "/path/to/publicKey.pub" + } + ] +} +``` +The contents of the public key file must contain the public key only, e.g.: +``` +/+UuD63zItL1EbjxkKUljMgG8Z1w0AJ8pNOR4iq2yQc= +``` + +The contents of the private key file must contain the private key in the Inline key pair format, e.g.: +```json +{ + "type" : "unlocked", + "data" : { + "bytes" : "DK0HDgMWJKtZVaP31mPhk6TJNACfVzz7VZv2PsQZeKM=" + } +} +``` + +or + +```json +{ + "data": { + "aopts": { + "variant": "id", + "memory": 1048576, + "iterations": 10, + "parallelism": 4, + }, + "snonce": "x3HUNXH6LQldKtEv3q0h0hR4S12Ur9pC", + "asalt": "7Sem2tc6fjEfW3yYUDN/kSslKEW0e1zqKnBCWbZu2Zw=", + "sbox": "d0CmRus0rP0bdc7P7d/wnOyEW14pwFJmcLbdu2W3HmDNRWVJtoNpHrauA/Sr5Vxc" + }, + "type": "argon2sbox" +} ``` + +Passwords must be provided so that Tessera can decrypt and use the private keys. Passwords can be provided in multiple ways: + +| | Description | +|--------|--------------| +| File | `"passwordFile": "/path/to/pwds.txt"`
Must contain only one password per line. Empty lines should be used for unlocked keys. Passwords must be provided in the order that key pairs are defined in the config. | +| Direct | `"passwords": ["pwd1", "pwd2", ...]`
Empty strings should be used for unlocked keys. Passwords must be provided in the order that key pairs are defined in the config. Not recommended for production use. | +| CLI | Tessera will prompt on the CLI for the passwords of any encrypted keys that have not had passwords provided in the config. This process only needs to be performed once, when starting the node. | + +### Azure Key Vault key pairs +The keys in the pair are stored as secrets in an Azure Key Vault. This requires providing the vault url and the secret IDs for both keys: +```json "keys": { "azureKeyVaultConfig": { "url": "https://my-vault.vault.azure.net" @@ -105,11 +184,12 @@ The keys in the pair are stored as secrets in an Azure Key Vault. This requires This example configuration will retrieve the specified versions of the secrets `Key` and `Pub` from the key vault with DNS name `https://my-vault.vault.azure.net`. If no version is specified then the latest version of the secret is retrieved. -> Environment variables must be set if using an Azure Key Vault, for more information see [Setting up an Azure Key Vault](../../Tessera%20Services/Keys/Setting%20up%20an%20Azure%20Key%20Vault) +!!! info + Environment variables must be set if using an Azure Key Vault, for more information see [Setting up an Azure Key Vault](../../Tessera%20Services/Keys/Setting%20up%20an%20Azure%20Key%20Vault) -#### 4. Hashicorp Vault key pairs +### Hashicorp Vault key pairs The keys in the pair are stored as a secret in a Hashicorp Vault. Additional configuration can also be provided if the Vault is configured to use TLS and if the AppRole auth method is being used at a different path to the default (`approle`): -``` +```json "hashicorpKeyVaultConfig": { "url": "https://localhost:8200", "tlsKeyStorePath": "/path/to/keystore.jks", @@ -132,38 +212,28 @@ This example configuration will retrieve version 1 of the secret `engine/secret` If no `hashicorpVaultSecretVersion` is provided then the latest version for the secret will be retrieved by default. Tessera requires TLS certificates and keys to be stored in `.jks` Java keystore format. If the `.jks` files are password protected then the following environment variables must be set: + * `HASHICORP_CLIENT_KEYSTORE_PWD` * `HASHICORP_CLIENT_TRUSTSTORE_PWD` -> If using a Hashicorp Vault additional environment variables must be set and a version 2 K/V secret engine must be enabled. For more information see [Setting up a Hashicorp Vault](../../Tessera%20Services/Keys/Setting%20up%20a%20Hashicorp%20Vault). +!!! info + If using a Hashicorp Vault additional environment variables must be set and a version 2 K/V secret engine must be enabled. For more information see [Setting up a Hashicorp Vault](../../Tessera%20Services/Keys/Setting%20up%20a%20Hashicorp%20Vault). -#### 5. Filesystem key pairs -The keys in the pair are stored in files: -``` -"keys": { - "passwordFile": "/path/to/passwords", - "keyData": [ - { - "privateKeyPath": "/path/to/privateKey.key", - "publicKeyPath": "/path/to/publicKey.pub" - } - ] -} -``` -The contents of the public key file must contain the public key only, e.g.: -``` -/+UuD63zItL1EbjxkKUljMgG8Z1w0AJ8pNOR4iq2yQc= -``` +## Providing key passwords at runtime +Tessera will start a CLI password prompt if it has incomplete password data for its locked keys. This prompt can be used to provide the required passwords for each key without having to provide them in the configfile itself. + +For example: + +```bash +tessera -configfile path/to/config.json +Password for key[0] missing or invalid. +Attempt 1 of 2. Enter a password for the key + +2019-12-09 13:48:16.159 [main] INFO c.q.t.config.keys.KeyEncryptorImpl - Decrypting private key +2019-12-09 13:48:19.364 [main] INFO c.q.t.config.keys.KeyEncryptorImpl - Decrypted private key +# Tessera startup continues as normal +``` -The contents of the private key file must contain the private key in the config format, e.g.: -``` -{ - "type" : "unlocked", - "data" : { - "bytes" : "DK0HDgMWJKtZVaP31mPhk6TJNACfVzz7VZv2PsQZeKM=" - } -} -``` ## Multiple Keys If wished, multiple key pairs can be specified for a Tessera node. In this case, any one of the public keys can be used to address a private transaction to that node. Tessera will sequentially try each key to find one that can decrypt the payload. This can be used, for example, to simplify key rotation. diff --git a/docs/Privacy/Tessera/Configuration/Sample Configuration.md b/docs/Privacy/Tessera/Configuration/Sample Configuration.md index 8b77537e37..a633b763ad 100644 --- a/docs/Privacy/Tessera/Configuration/Sample Configuration.md +++ b/docs/Privacy/Tessera/Configuration/Sample Configuration.md @@ -4,6 +4,9 @@ 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.2 - latest release](../Tessera%20v0.10.2%20sample%20settings) | +| [0.10](../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/TLS.md b/docs/Privacy/Tessera/Configuration/TLS.md index cb92264eb7..186ae74270 100644 --- a/docs/Privacy/Tessera/Configuration/TLS.md +++ b/docs/Privacy/Tessera/Configuration/TLS.md @@ -83,18 +83,18 @@ By setting `"generateKeyStoreIfNotExisted": "true"`, Tessera will check whether Below is a config sample for using the `.pem` file format: ```json "sslConfig" : { - "tls" : "STRICT", - "generateKeyStoreIfNotExisted" : "false", - "serverTlsKeyPath" : "server-key.pem", - "serverTlsCertificatePath" : "server-cert.pem", - "serverTrustCertificates" : ["server-trust.pem"] - "serverTrustMode" : "CA", - "clientTlsKeyPath" : "client-key.pem", - "clientTlsCertificatePath" : "client-cert.pem", - "clientTrustCertificates" : ["client-trust.pem"] - "clientTrustMode" : "TOFU", - "knownClientsFile" : "knownClients", - "knownServersFile" : "knownServers" + "tls" : "STRICT", + "generateKeyStoreIfNotExisted" : "false", + "serverTlsKeyPath" : "server-key.pem", + "serverTlsCertificatePath" : "server-cert.pem", + "serverTrustCertificates" : ["server-trust.pem"] + "serverTrustMode" : "CA", + "clientTlsKeyPath" : "client-key.pem", + "clientTlsCertificatePath" : "client-cert.pem", + "clientTrustCertificates" : ["client-trust.pem"] + "clientTrustMode" : "TOFU", + "knownClientsFile" : "knownClients", + "knownServersFile" : "knownServers" } ``` @@ -102,67 +102,67 @@ Below is a config sample for using the `.pem` file format: The Trust Mode for both client and server must also be specified. Multiple trust modes are supported: `TOFU`, `WHITELIST`, `CA`, `CA_OR_TOFU`, and `NONE`. * `TOFU` (Trust-on-first-use) - Only the first node that connects identifying as a certain host will be allowed to connect as the same host in the future. When connecting for the first time, the host and its certificate will be added to `knownClientsFile` (for server), or `knownServersFile` (for client). These files will be generated if not already existed, using the values specified in `knownClientsFile` and `knownServersFile`. - - A config sample for `TOFU` trust mode is: - - ```json - "sslConfig" : { - "tls" : "STRICT", - "generateKeyStoreIfNotExisted" : "true", - "serverKeyStore" : "server-keystore", - "serverKeyStorePassword" : "tessera", - "serverTrustMode" : "TOFU", - "clientKeyStore" : "client-keystore", - "clientKeyStorePassword" : "tessera", - "clientTrustMode" : "TOFU", - "knownClientsFile" : "knownClients", - "knownServersFile" : "knownServers" - } - ``` + Only the first node that connects identifying as a certain host will be allowed to connect as the same host in the future. When connecting for the first time, the host and its certificate will be added to `knownClientsFile` (for server), or `knownServersFile` (for client). These files will be generated if not already existed, using the values specified in `knownClientsFile` and `knownServersFile`. + + A config sample for `TOFU` trust mode is: + + ```json + "sslConfig" : { + "tls" : "STRICT", + "generateKeyStoreIfNotExisted" : "true", + "serverKeyStore" : "server-keystore", + "serverKeyStorePassword" : "tessera", + "serverTrustMode" : "TOFU", + "clientKeyStore" : "client-keystore", + "clientKeyStorePassword" : "tessera", + "clientTrustMode" : "TOFU", + "knownClientsFile" : "knownClients", + "knownServersFile" : "knownServers" + } + ``` * `WHITELIST` - Only nodes that have previously connected to this node and have been added to the `knownClients` file will be allowed to connect. Similarly, this node will only be allowed to make connections to nodes that have been added to the `knownServers` file. This trust mode will not add new entries to the `knownClients` or `knownServers` files. - - With this trust mode, the whitelist files (`knownClientsFile` and `knownServersFile`) must be provided. - - A config sample for `WHITELIST` trust mode is: - - ```json - "sslConfig" : { - "tls" : "STRICT", - "generateKeyStoreIfNotExisted" : "true", - "serverKeyStore" : "server-keystore", - "serverKeyStorePassword" : "tessera", - "serverTrustMode" : "WHITELIST", - "clientKeyStore" : "client-keystore", - "clientKeyStorePassword" : "tessera", - "clientTrustMode" : "WHITELIST", - "knownClientsFile" : "knownClients", - "knownServersFile" : "knownServers" - } - ``` + Only nodes that have previously connected to this node and have been added to the `knownClients` file will be allowed to connect. Similarly, this node will only be allowed to make connections to nodes that have been added to the `knownServers` file. This trust mode will not add new entries to the `knownClients` or `knownServers` files. + + With this trust mode, the whitelist files (`knownClientsFile` and `knownServersFile`) must be provided. + + A config sample for `WHITELIST` trust mode is: + + ```json + "sslConfig" : { + "tls" : "STRICT", + "generateKeyStoreIfNotExisted" : "true", + "serverKeyStore" : "server-keystore", + "serverKeyStorePassword" : "tessera", + "serverTrustMode" : "WHITELIST", + "clientKeyStore" : "client-keystore", + "clientKeyStorePassword" : "tessera", + "clientTrustMode" : "WHITELIST", + "knownClientsFile" : "knownClients", + "knownServersFile" : "knownServers" + } + ``` * `CA` - Only nodes with a valid certificate and chain of trust are allowed to connect. For this trust mode, trust stores must be provided and must contain a list of trust certificates. - - A config sample for `CA` trust mode is: - - ```json - "sslConfig" : { - "tls" : "STRICT", - "generateKeyStoreIfNotExisted" : "false", //You can't generate trust stores when using CA - "serverKeyStore" : "server-keystore", - "serverKeyStorePassword" : "tessera", - "serverTrustStore" : "server-truststore", - "serverTrustStorePassword" : "tessera", - "serverTrustMode" : "CA", - "clientKeyStore" : "client-keystore", - "clientKeyStorePassword" : "tessera", - "clientTrustStore" : "client-truststore", - "clientTrustStorePassword" : "tessera", - "clientTrustMode" : "CA", - "knownClientsFile" : "knownClients", - "knownServersFile" : "knownServers" - } - ``` + Only nodes with a valid certificate and chain of trust are allowed to connect. For this trust mode, trust stores must be provided and must contain a list of trust certificates. + + A config sample for `CA` trust mode is: + + ```json + "sslConfig" : { + "tls" : "STRICT", + "generateKeyStoreIfNotExisted" : "false", //You can't generate trust stores when using CA + "serverKeyStore" : "server-keystore", + "serverKeyStorePassword" : "tessera", + "serverTrustStore" : "server-truststore", + "serverTrustStorePassword" : "tessera", + "serverTrustMode" : "CA", + "clientKeyStore" : "client-keystore", + "clientKeyStorePassword" : "tessera", + "clientTrustStore" : "client-truststore", + "clientTrustStorePassword" : "tessera", + "clientTrustMode" : "CA", + "knownClientsFile" : "knownClients", + "knownServersFile" : "knownServers" + } + ``` 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 0000000000..58a6fe5ca2 --- /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/Configuration/Tessera v0.10.2 sample settings.md b/docs/Privacy/Tessera/Configuration/Tessera v0.10.2 sample settings.md new file mode 100644 index 0000000000..03df107bc2 --- /dev/null +++ b/docs/Privacy/Tessera/Configuration/Tessera v0.10.2 sample settings.md @@ -0,0 +1,153 @@ +**Changes:** + +- The `keys.keyData.passwords` field is no longer supported. Instead, use `keys.keyData.passwordFile` or utilise the [CLI password prompt](../Keys#providing-key-passwords-at-runtime) when starting the node. + +- Added configuration to choose alternative curves/symmetric ciphers. If no encryptor configuration is provided it will default to NaCl (see [Supporting alternative curves in Tessera](../Configuration Overview#supporting-alternative-curves-in-tessera) for more details). + + e.g. + ``` + "encryptor": { + "type":"EC", + "properties":{ + "symmetricCipher":"AES/GCM/NoPadding", + "ellipticCurve":"secp256r1", + "nonceLength":"24", + "sharedKeyLength":"32" + } + } + ``` + +**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": { + "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 + }, + "encryptor": { + "type": "Enumeration: NACL, EC", + "properties":{ + "symmetricCipher":"String (defaults to AES/GCM/NoPadding if type = EC)", + "ellipticCurve": "String (defaults to secp256r1 if type = EC)", + "nonceLength": "String (defaults to 24 if type = EC)", + "sharedKeyLength": "String (defaults to 32 if type = EC)" + } + } +} +``` diff --git a/docs/Privacy/Tessera/Configuration/Using CLI to override config.md b/docs/Privacy/Tessera/Configuration/Using CLI to override config.md index 15d1be27d5..3f3534d151 100644 --- a/docs/Privacy/Tessera/Configuration/Using CLI to override config.md +++ b/docs/Privacy/Tessera/Configuration/Using CLI to override config.md @@ -1,4 +1,4 @@ -CLI options can be used to add to, or override, configuration defined in a `configfile`. +CLI options can be used to add to, or override, configuration defined in a `configfile` or for `keygen`. Standard Tessera CLI options are prefixed with a single hyphen (e.g. `-configfile `), whilst the config override options are prefixed with a double hyphen (e.g. `--alwaysSendTo `). Use `tessera help` to see a complete list of CLI options. @@ -45,3 +45,16 @@ then Tessera will be started with the following equivalent configuration: } ``` As demonstrated in this example, in certain cases multiple values can be provided by repeating the CLI option. This is supported for the `peer.url`, `alwaysSendTo`, `server.sslConfig.serverTrustCertificates` and `server.sslConfig.clientTrustCertificates` options. + +If you want to generate a key with alternative curve other than default NaCl, use the `encryptor.type` override as follows: + +``` +tessera -keygen --encryptor.type EC +``` +The override could also be used to override the value in the config file +``` +tessera -configfile --encryptor.type EC +``` + +!!! info + Please note with the above config, the default curve properties will be used. To update properties such as using a different curve or length, etc... please use the config file - click [here](../Tessera v0.10.2 sample settings) for sample diff --git a/docs/Privacy/Tessera/How Tessera Works.md b/docs/Privacy/Tessera/How Tessera Works.md index 35563bf670..a68316afe9 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/Tessera Services/Keys/Keys.md b/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md index d3611a7155..d6c5694e19 100644 --- a/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md +++ b/docs/Privacy/Tessera/Tessera Services/Keys/Keys.md @@ -1,5 +1,5 @@ ## Generating keys - + Key generation can be used in multiple ways: 1. Generate a key pair and save in new files `.pub` and `.key`: @@ -67,6 +67,11 @@ If you wish to generate an unlocked key, `/dev/null` can be used for stdin to te An updated `.json` configfile is printed to the terminal (or to a file if using the `-output` CLI option). No changes are made to the `config.json` file itself. +!!! note + By default the `-keygen` commands generate [NaCl](https://nacl.cr.yp.to/) compatible keys. + + As of Tessera v0.10.2, the `--encryptor.type=EC` CLI option can be provided to generate keys of different types. See [encryptor config](../../../Configuration/Configuration Overview/#encryptor-supporting-alternative-curves-in-tessera) for more details. + ## Securing private keys Generated private keys can be encrypted with a password. This is prompted for on the console during key generation. After generating password-protected keys, the password must be added to your configuration to ensure Tessera can read the keys. The password is not saved anywhere but must be added to the configuration else the key will not be able to be decrypted. @@ -112,3 +117,8 @@ Password update can be used in multiple ways. Running any of these commands wil tessera --keys.keyData.privateKeyPath --keys.keyData.config.data.aopts.algorithm --keys.keyData.config.data.aopts.iterations --keys.keyData.config.data.aopts.memory --keys.keyData.config.data.aopts.parallelism ``` All options have been overriden here but only the options you wish to alter from their defaults need to be provided. + +!!! note + By default the `-updatepassword` commands can be used to update the password of [NaCl](https://nacl.cr.yp.to/) compatible keys. + + As of Tessera v0.10.2, the `--encryptor.type=EC` CLI option can be provided to update keys of different types. See [encryptor config](../../../Configuration/Configuration Overview/#encryptor-supporting-alternative-curves-in-tessera) for more details. diff --git a/docs/Privacy/Tessera/Usage/Interface & API.md b/docs/Privacy/Tessera/Usage/Interface & API.md index 276a497987..bfb68597d5 100644 --- a/docs/Privacy/Tessera/Usage/Interface & API.md +++ b/docs/Privacy/Tessera/Usage/Interface & API.md @@ -2,7 +2,7 @@ All interfaces can be set to run over HTTP, GRPC or HTTP-over-Unix-Sockets. -### gRPC (for inter-node communication) +### gRPC for inter-node communication (Deprecated) We currently have an implementation of gRPC for peer node communication as experiment API. This is not enabled on Quorum yet, but between Tessera nodes they can be enabled by adding in a couple of properties in the configuration file as child elements of `serverConfig`. @@ -12,6 +12,9 @@ We currently have an implementation of gRPC for peer node communication as exper Please note that communication between Quorum and Tessera are still via unix socket. This communication flag provides additional options for Tessera peer-to-peer communication. If gRPC is the option specified, please ensure the peers urls are provided with the appropriate ports. +!!! info + gRPC as a protocol for peer-to-peer communication will be removed from Tessera version 0.10.2 + --- ### Tessera to Tessera - Public API @@ -28,6 +31,7 @@ The following endpoints are advertised on this interface: * `/push` * `/resend` * `/partyinfo` +* `/partyinfo/validate` ### Third Party - Public API @@ -40,6 +44,8 @@ The following endpoints are advertised on this interface: * `/version` * `/upcheck` * `/storeraw` +* `/keys` +* `/partyinfo/keys` ### Quorum to Tessera - Private API @@ -48,6 +54,7 @@ Quorum uses this API to: - Send and receive details of private transactions The following endpoints are advertised on this interface: + - `/version` - `/upcheck` - `/sendraw` @@ -59,12 +66,13 @@ The following endpoints are advertised on this interface: ### Admin API Admins should use this API to: + - Access information about the Tessera node - Make changes to the configuration of the Tessera node The following endpoints are advertised on this API: + - `/peers` - Add to, and retrieve from, the Tessera node's peers list -- `/keypairs` - Retrieve all public keys or search for a particular public key in use by the Tessera node ## API Details @@ -89,6 +97,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/docs/README.md b/docs/README.md index f52813d643..9492d13d41 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,26 @@ +[![Documentation Status](https://readthedocs.org/projects/goquorum/badge/?version=latest)](http://docs.goquorum.com/en/latest/?badge=latest) # Quorum documentation -New Quorum documentation is now published on https://goquorum.readthedocs.io/ +New Quorum documentation is now published on https://docs.goquorum.com/ + +## How to contribute + +Quorum documentation files are written in Markdown and configured with a +YAML configuration file from [mkdocs](https://www.mkdocs.org/) + +The documentation site uses [Material theme](https://squidfunk.github.io/mkdocs-material/) +which has been configured with number of theme [extensions](https://squidfunk.github.io/mkdocs-material/extensions/admonition/) +to enhance documenting experience + +To contribute, here is 3 simple steps + +- Use Python to install `mkdocs` and related dependencies + ```bash + pip install -r requirements.txt + ``` +- Add/Modify desired documentation files and preview the site + ```bash + mkdocs serve + ``` +- Commit and raise PR against master \ No newline at end of file diff --git a/docs/RemixPlugin/Getting started.md b/docs/RemixPlugin/Getting started.md new file mode 100644 index 0000000000..1e57a95ab3 --- /dev/null +++ b/docs/RemixPlugin/Getting started.md @@ -0,0 +1,49 @@ +# Getting Started with the Quorum Plugin for Remix + +1. Go to the [Remix IDE](https://remix.ethereum.org), click on the Plugins tab, scroll down to **Quorum Network**, and Activate. + + ![quorum_network](./images/quorum_network.png) + +2. Accept the permission to allow the plugin to retrieve compilation results. This allows our plugin to use the solidity compiler to get the compiled contract binary to deploy to your Quorum node. + + ![permission](./images/permission.png) + +3. The plugin should now be included in the icons on the left side. Click on the Quorum icon to show the plugin. + + ![quorum_tab](./images/tab_icon.png) + +4. Input the Geth RPC url and hit enter. If you are currently running the quorum-examples 7nodes network, the first node's url is http://localhost:22000 + + ![geth_rpc](./images/geth_rpc.png) + +5. If the node is running, the plugin should now say Connected and the rest of the UI will have appeared. + + ![ui_ready](./images/ui_ready.png) + +6. The Quorum plugin uses results from Remix's Solidity compiler, so pull up some contract code and compile it like you normally would in Remix. The plugin will automatically receive the compiled code on each new compilation. + +7. Once you have a contract compiled, it will automatically be selected in the Compiled Contracts dropdown. Input any constructor values and deploy. + + ![deploy](./images/deploy.png) + +8. If successful, the contract will show up in a collapsed view under 'Deployed Contracts'. Click the caret to expand. + + ![contract_collapsed](./images/contract_collapsed.png) + +9. From here you can call methods on the contract. + + ![method_call](./images/method_call.png) + +10. To create a private contract, add your Tessera public keys one at a time to the Private For multi-select box. Press enter after inputting each one to save and select. + + ![private_add](./images/private_add.png) + +11. Add as many peers as you want, then deploy the contract again like you did in step 7. + + ![private_multiple](./images/private_multiple.png) + +12. After deploying and expanding the new contract, you should see the public keys that you selected in the widget. Every method call will include the selected keys automatically. + + ![deployed_private](./images/deployed_private.png) + +13. Please open a github issue or reach out to us on our [Slack](https://bit.ly/quorum-slack) with any feedback or questions! diff --git a/docs/RemixPlugin/Overview.md b/docs/RemixPlugin/Overview.md new file mode 100644 index 0000000000..6763451d46 --- /dev/null +++ b/docs/RemixPlugin/Overview.md @@ -0,0 +1,17 @@ +# Quorum Plugin for Remix + +The Quorum plugin for Ethereum's Remix IDE adds support for creating and interacting with private contracts on a Quorum network. + +![screenshot](./images/quorum-remix.png "screenshot") + +## Getting Started + +Just go to the [Remix IDE](https://remix.ethereum.org) and activate the **Quorum Network** plugin on the plugins page. For step-by-step instructions, go to the [Getting Started](../Getting%20started) doc. + +## Common Issues + +**HTTP/HTTPS:** +- Most browsers will not allow you to connect to an HTTP resource if you are currently on an HTTPS page. Since our plugin is currently loaded from HTTPS, it will not let you connect to a Quorum node that doesn't have an https url. **Chrome makes an exception for localhost**, so you should be able to connect to http://localhost:22000, for example. Firefox seems to be a little more strict than Chrome at the moment and does not allow these localhost calls. We are tracking this issue in [quorum-remix#8](https://github.com/jpmorganchase/quorum-remix/issues/8), but until that is fixed please use Chrome or another browser that doesn't block these requests. + +## Contributing +Quorum Plugin for Remix is built on open source and we invite you to contribute enhancements. Upon review you will be required to complete a Contributor License Agreement (CLA) before we are able to merge. If you have any questions about the contribution process, please feel free to send an email to [info@goquorum.com](mailto:info@goquorum.com). diff --git a/docs/RemixPlugin/images/contract_collapsed.png b/docs/RemixPlugin/images/contract_collapsed.png new file mode 100644 index 0000000000..17e9c04bad Binary files /dev/null and b/docs/RemixPlugin/images/contract_collapsed.png differ diff --git a/docs/RemixPlugin/images/deploy.png b/docs/RemixPlugin/images/deploy.png new file mode 100644 index 0000000000..be4ebf3fb8 Binary files /dev/null and b/docs/RemixPlugin/images/deploy.png differ diff --git a/docs/RemixPlugin/images/deployed_private.png b/docs/RemixPlugin/images/deployed_private.png new file mode 100644 index 0000000000..bdf5055ca5 Binary files /dev/null and b/docs/RemixPlugin/images/deployed_private.png differ diff --git a/docs/RemixPlugin/images/geth_rpc.png b/docs/RemixPlugin/images/geth_rpc.png new file mode 100644 index 0000000000..70ef0f693c Binary files /dev/null and b/docs/RemixPlugin/images/geth_rpc.png differ diff --git a/docs/RemixPlugin/images/method_call.png b/docs/RemixPlugin/images/method_call.png new file mode 100644 index 0000000000..0c1bbf3e32 Binary files /dev/null and b/docs/RemixPlugin/images/method_call.png differ diff --git a/docs/RemixPlugin/images/method_success.png b/docs/RemixPlugin/images/method_success.png new file mode 100644 index 0000000000..d79f4232bd Binary files /dev/null and b/docs/RemixPlugin/images/method_success.png differ diff --git a/docs/RemixPlugin/images/permission.png b/docs/RemixPlugin/images/permission.png new file mode 100644 index 0000000000..bfd5c11a6f Binary files /dev/null and b/docs/RemixPlugin/images/permission.png differ diff --git a/docs/RemixPlugin/images/plugin_tab.png b/docs/RemixPlugin/images/plugin_tab.png new file mode 100644 index 0000000000..2faf01fdef Binary files /dev/null and b/docs/RemixPlugin/images/plugin_tab.png differ diff --git a/docs/RemixPlugin/images/private_add.png b/docs/RemixPlugin/images/private_add.png new file mode 100644 index 0000000000..8f7f327579 Binary files /dev/null and b/docs/RemixPlugin/images/private_add.png differ diff --git a/docs/RemixPlugin/images/private_multiple.png b/docs/RemixPlugin/images/private_multiple.png new file mode 100644 index 0000000000..12856dc279 Binary files /dev/null and b/docs/RemixPlugin/images/private_multiple.png differ diff --git a/docs/RemixPlugin/images/quorum-remix.png b/docs/RemixPlugin/images/quorum-remix.png new file mode 100644 index 0000000000..75aa561577 Binary files /dev/null and b/docs/RemixPlugin/images/quorum-remix.png differ diff --git a/docs/RemixPlugin/images/quorum_logo.png b/docs/RemixPlugin/images/quorum_logo.png new file mode 100644 index 0000000000..0943898939 Binary files /dev/null and b/docs/RemixPlugin/images/quorum_logo.png differ diff --git a/docs/RemixPlugin/images/quorum_network.png b/docs/RemixPlugin/images/quorum_network.png new file mode 100644 index 0000000000..d082c71e3a Binary files /dev/null and b/docs/RemixPlugin/images/quorum_network.png differ diff --git a/docs/RemixPlugin/images/quorum_tab.png b/docs/RemixPlugin/images/quorum_tab.png new file mode 100644 index 0000000000..7f6cc5424e Binary files /dev/null and b/docs/RemixPlugin/images/quorum_tab.png differ diff --git a/docs/RemixPlugin/images/tab_icon.png b/docs/RemixPlugin/images/tab_icon.png new file mode 100644 index 0000000000..091108d698 Binary files /dev/null and b/docs/RemixPlugin/images/tab_icon.png differ diff --git a/docs/RemixPlugin/images/ui_ready.png b/docs/RemixPlugin/images/ui_ready.png new file mode 100644 index 0000000000..4d7352f48f Binary files /dev/null and b/docs/RemixPlugin/images/ui_ready.png differ diff --git a/docs/Security/Framework/Decentralized Application/Frontend Components.md b/docs/Security/Framework/Decentralized Application/Frontend Components.md new file mode 100644 index 0000000000..b7c942c4da --- /dev/null +++ b/docs/Security/Framework/Decentralized Application/Frontend Components.md @@ -0,0 +1,11 @@ +## Frontend + +As any traditional application, dApps Client/Server component has to follow application security best practices. +Its recommended to use a Secure Software Development Lifecycle (SSDLC) to implement any application. +In general Secure Development Lifecycle include the following phases : + +- Risk Assessment Phase. +- Threat Modeling, and Secure Design Review Phase. +- Static Source Code Analysis Phase. +- Security Testing, and Manual Secure Source Review Phase. +- Security Assessment of Configuration of Deployment Pipeline Phase. diff --git a/docs/Security/Framework/Decentralized Application/Smart Contracts Security.md b/docs/Security/Framework/Decentralized Application/Smart Contracts Security.md new file mode 100644 index 0000000000..4284d2ebda --- /dev/null +++ b/docs/Security/Framework/Decentralized Application/Smart Contracts Security.md @@ -0,0 +1,129 @@ +**Smart Contracts Security** must be considered as any other application security, it might contain logical vulnerabilities, insecure design and it might run on vulnerable components (ledgers). However Smart Contracts +are the core element of Ethereum Blockchain, unlike other software concepts it is constrained by several Blockchain Technology primitives: + +- Smart Contracts runtime is sandboxed, this means obtaining a secure randomness source is hard. +- Smart Contracts can hold, transfer or destroy funds making them an economical risk component. +- Smart Contracts cannot be directly upgraded unless an upgrade mechanism is introduced from the design phase. +- Smart Contracts are immutable, and have an irrevocable self destruction feature. +- Smart Contracts can have one or multiple owners. + +### Ownership +Unlike traditional software management process Smart Contracts support the following technologically enforced ownership model: + +**Single Ownership**: +The contract has one owner who is responsible for the contract administration process. + +**Shared Custody Ownership**: +Suitable for agreement between two or more parties in a network of N parties, where any party can unilaterally perform administrative action over the contract. + +**Consortium Based Ownership**: +Is a form of expanded Shared Custody Ownership that requires consensus over the administrative actions. + + +### Security Patterns: + +**Checks-Effects-Interaction Pattern**: Interacting with other contracts should always be the last step in contract function. It’s crucial that the current contract has finished its functionality before handling control to other contract and does not depend on the execution of the other contract. + +**Circuit Breaker**: is logical emergency stop execution logic. Implementing emergency stops in logic of smart contract is a good security practice. A Circuit breaker can be triggered manually by trusted parties included in the contract like the contract owner or by using programmatic consensus rules that automatically trigger the circuit breaker when the defined conditions are met. + +**Rate Limit**: smart contract function within a period of time allows better control of resources that can be abused. + +**Speed Bumps**: introduces a delay in the action execution allowing a time to act if action is considered malicious. + + +### Common Contract Vulnerabilities + +**Reentrancy**: Reentrancy occurs when external contract calls are allowed to make new calls to the calling contract before the initial execution is complete. For a function, this means that the contract state may change in the middle of its execution as a result of a call to an untrusted contract or the use of a low level function with an external address. + +**Access Control**: While insecure visibility settings give attackers straightforward ways to access a contract's private values or logic, access control bypasses are sometimes more subtle. These vulnerabilities can occur when contracts use the deprecated tx.origin to validate callers, handle large authorization logic with lengthy require and make reckless use of delegatecall in proxy libraries or proxy contracts. + +**Arithmetic**: Integer overflows and underflows are not a new class of vulnerability, but they are especially dangerous in smart contracts, where unsigned integers are prevalent and most developers are used to simple int types (which are often just signed integers). If overflows occur, many benign-seeming codepaths become vectors for theft or denial of service. + +**Unchecked Low Level Calls**: One of the deeper features of Solidity are the low level functions such as call(), callcode(), delegatecall() and send(). Their behavior in accounting for errors is quite different from other Solidity functions, as they will not propagate (or bubble up) and will not lead to a total reversion of the current execution. Instead, they will return a boolean value set to false, and the code will continue to run. This could surprise developers and, if the return value of such low-level calls are not checked, it could lead to fail-opens and other unwanted outcomes + +**Bad Randomness**: Is hard to get right in Ethereum. While Solidity offers functions and variables that can access apparently hard-to-predict values, they are generally either more public than they seem. Because randomness sources are to an extent predictable in ethereum, malicious users can generally replicate it and attack the function relying on its unpredictablility and this applies to dApps built on top of Quorum too. + +**Front Running**: In public ethereum client miners always get rewarded via gas fees for running code on behalf of externally owned addresses (EOA), users can specify higher fees to have their transactions mined more quickly. Since the Ethereum blockchain is public, everyone can see the contents of others' pending transactions. This means if a given user is revealing the solution to a puzzle or other valuable secret, a malicious user can steal the solution and copy their transaction with higher fees to preempt the original solution. If developers of smart contracts are not careful, this situation can lead to practical and devastating front-running attacks. On the other hand since Quorum does not uses Proof Of Work (PoW) in its consensus algorithm and the gas cost is zero, PoW mining related vulnerabilities are not applicable when building on top of Quorum, however fron-running remains a risk and will dependent on the consensus algorithm in use. + +**Time Manipulation**: From locking a token sale to unlocking funds at a specific time, contracts sometimes need to rely on the current time. This is usually done via block.timestamp or its alias now in Solidity. In public ethereum this value comes from the miners, however in Quorum it comes from the minter, or validators, as result smart contracts should avoid relying strongly on the block time for critical decision making. Note that block.timestamp should not be used for the generation of random numbers. + +**Short Addresses**: attacks are a side-effect of the EVM itself accepting incorrectly padded arguments. Attackers can exploit this by using specially-crafted addresses to make poorly coded clients encode arguments incorrectly before including them in transactions. + + +### Security Checklist + +#### Ownership + +!!! success "No ownership contacts must be prevented in Enteprise Blockchain." + +!!! success "Contracts must include initilization phase where all owners are clearly identified and set `init(owners_list)`." + +!!! success "Identify contract ownership model before starting the design of the smart contract logic." + +!!! success "Define the consensus model for Constortium Based Ownership." + +!!! success "Contract upgradability and ownership functionalies must verify new addresses are valid." + +!!! success "Ownership relate events must be broadcasted to all the network participants." + +!!! success "In a Constortium based ownership structure changing activities that are bound to approval from Constortium members before they are commited (E.g editing Constortium structure) must have an aproval pending expiration date." + +!!! success "Constorium based voting must involve realtime notification through EVM event emition. " + +#### Contract Implementation + +!!! success "Contract should use a locked compiler version" + +!!! success "The compiler version should be consistent across all contracts" + +!!! success "Contract should not shadow or overwrite built-in functions" + +!!! success "Contract should never use tx.origin as authorization mechanism " + +!!! success "Contract should never use timestamp as source of randomness" + +!!! success "Contract should never use block number or hash as a source for randomness" + +!!! success "Contract should never use block number or timestamp as critical decision making conditions" + +!!! success "Contract should never misuse multiple inheritance " + +!!! success "Modifiers must perserve the contract state or performing an external call" + +!!! success "Contract should never contain cross function race conditions" + +!!! success "Contract should never use plain arithmetic computation instead safe math should be used" + +!!! success "Contract fallback functions should be free of unknown states that might introduce security implications" + +!!! success "Contract should avoid shadowed variables " + +!!! success "Contract public variables/functions should be reviewed to ensure visibility is appropriate" + +!!! success "Contract private variables should not contain sensitive data " + +!!! success "Contract functions should explicitly declare visibility" + +!!! success "Contract public functions should perform proper authorization checks " + +!!! success "Contract should validate the input of all public and external functions" + +!!! success "Contract using old solidity version constructor name must match contract name" + +!!! success "Contract should explicitly mark untrusted contracts as 'untrusted'" + +!!! success "Contract functions logic should perform state changing actions before making external calls" + +!!! success "Contract logic should use send() and transfer() over call.value when possible" + +!!! success "Contract usage of delegatecall should be properly handled" + +!!! success "Contract logic must correctly handle return value of any external call" + +!!! success "Contract must never assume it has been created with balance of 0 " + +!!! success "Contract logic should not contain loops that are vulnerable to denial of service attacks" + +!!! success "Multiparty contract logic action should not be dependent on a single party" + +!!! success "Prevent Toke transfers to 0x0 address" diff --git a/docs/Security/Framework/Overview.md b/docs/Security/Framework/Overview.md new file mode 100644 index 0000000000..0085db57c6 --- /dev/null +++ b/docs/Security/Framework/Overview.md @@ -0,0 +1,22 @@ +## Objectives +The **objective** of this framework is to provide an in-depth reference to Quorum and + Decentralized Applications (dApps) security best practices. + +The following outlines the *scope* of the framework: + +- Quorum architecture security +- Quorum network security guidelines +- Decentralized application (dApps) security best practices + + +## References ++ https://github.com/ethereum/go-ethereum/wiki ++ https://github.com/jpmorganchase/quorum/wiki ++ https://www.dasp.co/ ++ https://entethalliance.org/technical-documents/ ++ https://solidity.readthedocs.io/en/v0.5.7/# ++ https://nvlpubs.nist.gov/nistpubs/ir/2018/NIST.IR.8202.pdf ++ https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=925957 ++ https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE1TH5G ++ https://nvlpubs.nist.gov/nistpubs/CSWP/NIST.CSWP.04162018.pdf ++ https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt2r1.pdf diff --git a/docs/Security/Framework/Quorum Network Security/Consortium.md b/docs/Security/Framework/Quorum Network Security/Consortium.md new file mode 100644 index 0000000000..99567db473 --- /dev/null +++ b/docs/Security/Framework/Quorum Network Security/Consortium.md @@ -0,0 +1,37 @@ +When creating a Consortium the following elements should be taken in consideration: + +### Governance +Chosen structure must not only be appropriate to permit efficient and effective operations of the Consortium, +but also fulfill the concerns of those that form part of it equally. + +### Ownership +The nature of blockchain technology also increases the risk of accidental data exposure. In order to manage this risk +ownership of Intellectual Properties (IP), and assets should be documented, and agreed upon. + +### Liability +Most network operational activities are benign, but this is not true in all cases, +and even in otherwise low-risk Consortium, where the membership constitutes “market power” under the antitrust +laws, a significant percentage of the competitors in a given product or service space might be members. The potential +for inadvertent mistakes, as well as the level of potential scrutiny by government regulators, is higher. +In such a situation, individual members may wish to maintain tighter control over what can – and more importantly, what cannot – be done +by the organization, and its members without proper prior consensus in order to reduce the risk and liability. + +### Activities +Interconnecting multiple independent networks comes with risk factors. In order to +build a controls to minimize a risk, the activities that are expected to be performed in the network must be documented. + +### Security Checklist + +!!! success "Use Byzantine fault tolerant consensus protocol in case nodes are managed by un-trusted participants" + +!!! success "Consortium member should provide a reasonable network Service-Level Agreement (SLA)." + +!!! success "Ensure Private/Public payloads data is stored in a appropiate Geographical legislation area. " + +!!! success "Document the Consortium Governance Structure, Ownership, Liability, Memberships, Activities. " + +!!! success "Document the Organizational, and technological requirements to join the Consortium. " + +!!! success "Ensure Consortium members be known to every participant in the network." + +!!! success "Ensure Private/Public paylaod data is compliant with privacy policies. " diff --git a/docs/Security/Framework/Quorum Network Security/Node.md b/docs/Security/Framework/Quorum Network Security/Node.md new file mode 100644 index 0000000000..7da777c4ff --- /dev/null +++ b/docs/Security/Framework/Quorum Network Security/Node.md @@ -0,0 +1,64 @@ +**Quorum Node**, aka Quorum Client, is a thick-client whose Private Transaction feature operation depends on a Transaction Manager Client that encrypts and decrypts +private transactions payload. Both Quorum client and its dependencies i.e, Transaction Manager, Peers, and Enclave use traditional TCP/UDP transport layer to communicate. + +As any asset in a network its security depends on multiple elements (E.g the security of the Host, Data, and Accounts). In Quorum it will be the security of +the Client and Transaction Manager host/host-runtime, encryption keys, Consensus runtime and Network Access Controls. + +### Host Security +Any asset in a Quorum network (Client Host, Transaction Manager Host, Private Transaction Storage Host, ..etc ) must be hardened following industry best practices. A host IDS should be used to detect any malicious activities on the host. Direct access to the host should not be allowed, instead a jump server should be used and access limited to small number of administrators. +Operating systems, software and services will have vulnerabilities. Quorum network hosts must implement a robust patch management program. + +### Client Security +Quorum client instance exposes a JSON-Remote Procedure Call (RPC) interface through HTTP, Web Socket, or Inter-Process communication techniques. The JSON-RPC interfaces +allows the remote interaction with the ledger features, and Smart Contracts. The JSON-RPC interface must be secured in order to preserve the integrity of the ledger runtime. + +Each client in the network must be uniquely identified. In Quorum this is done by using nodes identity. Node identity is represented through a public key/private key, where +the public key identifies the node in the network. Quorum Smart Contract Permissioning models depends on nodes identity to authorize TCP level communication between nodes, as such securing +the private key of a node is a paramount activity required to prevent unauthorized node from joining the network. + + +### Users Security +Blockchain technology uses public key cryptography to protect the integrity of transactions and blocks. The security of a user’s Private keys is dependent on the security operation elements implemented to +preserve the Private key from compromise. In Ethereum Accounts Private keys are encrypted with user specified seed (password). Users password should never be saved across the ecosystem or stored in ledger host in any form. + +### Security Checklist + +#### Host + +!!! success "Harden Quorum Host Operating System (e.g remove irrelevant services, root access...etc)." + +!!! success "Disable direct remote network access to Quorum host management interface in production." + +!!! success "Use Host Based Intrusion Detection System (HIDS) to monitoring Quorum node host." + +!!! success "Enable Host Based Firewall Rules that enforces network access to JSON-RPC interface to only a preidentified, trusted and required systems." + +!!! success "Implement a robust Patch Management Program, and always keep the host updated to latest stable version." + +!!! success "Ensure host level Isolation of responsability between Quorum client and its dependency (e.g do not run the transaction manager and its database in the same host) " + +!!! success "Ensure Quorum network hosts run with appropiate service level agreement (SLA) that can ensure a defense against non-vulnerability based denial of service." + +#### Client + +!!! success "Enable Secure Transport Security (TLS) to encrypt all communications from/to JSON-RPC interface to prevent data leakage and man in the middle attacks (MITM)." + +!!! success "Enable Quorum Enterprise JSON-RPC authorization model to enforce atomic access controls to ledger modules functionalities (e.g personal.OpenWallet)." + +!!! success "Implement a robust Patch Management Program, and always keep the client updated to latest stable version." + +!!! success "Ensure Quorum client run configuration is not started with unlocked accounts options." + +!!! success "Ensure cross domain access of the JSON-RPC interface is configured appropriately. " + +!!! success "Ensure peer discovery is appropriately set based on the consortium requirements." + +!!! success "In Raft Based Consensus there is no guarantee a leader would not be acting maliciously, hence raft should not be used in environment where network ledger is managed by third party authorities." + +!!! success "Quorum clients must run with metrics collection capability in order to preserve operational security." + +#### Users + +!!! success "Accounts Private Key encryption password should never be stored in the ledger host in any form." + +!!! success "In an architecture where accounts private keys are not offloaded to ledger node clients, the encrypted private keys should be backed-up to secure environment regularly. " diff --git a/docs/Security/Security & Permissioning.md b/docs/Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md similarity index 100% rename from docs/Security/Security & Permissioning.md rename to docs/Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md diff --git a/docs/Security/Framework/Quorum Network Security/Opertional Considerations.md b/docs/Security/Framework/Quorum Network Security/Opertional Considerations.md new file mode 100644 index 0000000000..1cf85e7e00 --- /dev/null +++ b/docs/Security/Framework/Quorum Network Security/Opertional Considerations.md @@ -0,0 +1,28 @@ +### Monitoring +Monitoring a network for security events start from log collection activity. Quorum network as any other network should produce logs, that must be analyzed for anomalies. +The following parameters are of interest to be collected and analyzed: + + - Hosts access and events + - Ethereum accounts on the network + - Active ledger, transaction manager nodes in the network + - Public and Private transaction rates per account in the network. + - Number of public Smart contracts in the network. + - Network connections to ledger nodes and metadata. + - Consensus protocol metadata (E.g Block creation rate, and source ...etc) + +### Security Checklist + +!!! success "Ensure all activities of Quorum hosts are being logged to centralized log system" + +!!! success "Centralized log system most be able to provide query capabilites over the following parameters:" + - Ethereum accounts on the network + - Active ledger, transaction manager nodes in the network + - Public and Private transaction rates per account in the network. + - Number of public Smart contracts in the network. + - Network connections to ledger nodes and metadata. + - Consensus protocol metadata (E.g Block creation rate, and source ...etc) + +!!! success "Logs must be backed-up and integrity verified. " + +!!! success "An alerting system should be put in place in order to monitor consensus protocol anomalies " + diff --git a/docs/Security/Framework/Quorum Network Security/Transaction Manager.md b/docs/Security/Framework/Quorum Network Security/Transaction Manager.md new file mode 100644 index 0000000000..e404ed929d --- /dev/null +++ b/docs/Security/Framework/Quorum Network Security/Transaction Manager.md @@ -0,0 +1,35 @@ +### Tessera +[Tessera](../../../../Privacy/Tessera/Tessera/) is Quorum's Transaction Manager. Quorum privacy features depends on Tessera to Encrypt/Decrypt, and broadcast the orchestrations of a private transaction payload. +Tessera uses an enclave to perform the encryption/decryption of private transactions payload. The encryption keys should be stored in high secure environments such a hardware security module (HSM). +Tessera communication with its dependencies (Enclave, Quorum node, Payload Storage Database, Secret Storage Service) must be secured. To ensure the privacy and authentication of the communication between Tessera the network must be configured to Certificate Based Mutual Authentication (MTLS). + +### Encryption Keys +Encryption keys is the most critical element of the privacy model, if the encryption key is compromised the network loses its privacy. Tessera support integration with Trusted Platform Modules (TPM) and Hardware Security Modules (HSM) to reduce surface attack and provide highly secure environment. + +### Security Checklist + +!!! success "Tessera should run in independent network segment in production" + +!!! success "Tessera must leverage certificate based mutual authentication with its dependencies" + +!!! success "Secret storage services must support key rotation." + +!!! success "Depending on the deployment model Encryption Keys must be backed-up in offline secured locations." + +!!! success "Secret storage service must be in complete isolation of external network." + +!!! success "Tessera connection strings must not be stored in clear text in configuration files. " + +!!! success "Secret storage in cloud deployment should run under a single tenancy model." + +!!! success "Host firewall should be enabled, inbound and outbound traffic should be limited to only vault services and restricted to consumers of those services. This includes essential host services like DNS, and NTP." + +!!! success "Restrict remote access to Secret Storage instance to whitelisted IP addresses and enable MFA." + +!!! success "Disable remote root access to Tessera/Secret storage hosts." + +!!! success "Enable remote centralized logging for tessera and its dependencies." + +!!! success "Disable core dumps in tessera host." + +!!! success "Tessera upgrades should be using immutable strategy and frequent." \ No newline at end of file diff --git a/docs/images/ContractDesign.png b/docs/images/ContractDesign.png new file mode 100644 index 0000000000..be6a566b58 Binary files /dev/null and b/docs/images/ContractDesign.png differ diff --git a/docs/images/PermissionsModel.png b/docs/images/PermissionsModel.png new file mode 100644 index 0000000000..935b10cb7e Binary files /dev/null and b/docs/images/PermissionsModel.png differ diff --git a/docs/images/logo-48x48.png b/docs/images/logo-48x48.png new file mode 100644 index 0000000000..ac0dad1843 Binary files /dev/null and b/docs/images/logo-48x48.png differ diff --git a/docs/private-abigen.md b/docs/private-abigen.md new file mode 100644 index 0000000000..a6d5959728 --- /dev/null +++ b/docs/private-abigen.md @@ -0,0 +1,9 @@ +# Abigen with Quorum + +### Overview + +Abigen is a source code generator that converts smart contract ABI definitions into type-safe Go packages. In addition to the original capabilities provided by Ethereum described [here](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts). Quorum Abigen also supports private transactions. + +### Implementation + +`PrivateFrom` and `PrivateFor` fields have been added to the `bind.TransactOpts` which allows users to specify the public keys of the transaction manager (Tessera/Constellation) used to send and receive private transactions. The existing `ethclient` has been extended with a private transaction manager client to support sending `/storeraw` request. diff --git a/docs/requirements.txt b/docs/requirements.txt index 62b0ceade9..98b195287c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,6 +1,6 @@ mkdocs>=1.0 -pymdown-extensions==6.0 -mkdocs-material>=4.1 +pymdown-extensions==6.2 +mkdocs-material==4.4.3 Markdown==3.0.1 markdown-fenced-code-tabs==1.0.5 markdown-include==0.5.1 diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000000..ae67edf3dc --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,49 @@ +### Projections for 2018 / 2019 + + + +!!! abstract "Privacy" + + - Organization-level privacy addressing + - Asset Transfer with Privacy (ZKP) + - Private Contract extensibility + - Private State consensus (beyond exposing sync methods) + + +!!! abstract "Permissioning" + + - Support different role-types: Read vs Write nodes/accounts + - Smart Contract-based network permissions + - Authenticated / Protected RPC API access + - Consensus Node Whitelisting + +!!! abstract "Performance" + + - Performance benchmark guidelines + - Transaction parallelization R&D + - EVM optimizations + - eWASM support + +!!! abstract "Resiliency" + + - Transaction Manager clusters + - Transaction Manager auto-recover of data in case of loss + +!!! abstract "Scalability & Interoperability" + + - Raft scalability enhancements + - POA & other consensus algorithms + - Inter-quorum asset transfers + - Rate limiting (gas price) + +!!! abstract "Tooling" + + - One-click network deployments + - Database adapters for better querying + - Monitoring/Logging tools + - Identity management tools + +!!! abstract "Other / (Ongoing)" + + - Ensure EEA Specification compliance + - Merge upstream geth changes diff --git a/docs/theme/404.html b/docs/theme/404.html new file mode 100644 index 0000000000..52beb3b8b3 --- /dev/null +++ b/docs/theme/404.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block content %} +

404 - Not found

+{% endblock %} diff --git a/eth/api_backend.go b/eth/api_backend.go index a2159fcc94..733db6280b 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -18,6 +18,7 @@ package eth import ( "context" + "errors" "math/big" "github.com/ethereum/go-ethereum/accounts" @@ -40,6 +41,11 @@ import ( type EthAPIBackend struct { eth *Ethereum gpo *gasprice.Oracle + + // Quorum + // + // hex node id from node public key + hexNodeId string } // ChainConfig returns the active chain configuration. @@ -181,6 +187,11 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri } func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + // validation for node need to happen here and cannot be done as a part of + // validateTx in tx_pool.go as tx_pool validation will happen in every node + if b.hexNodeId != "" && !types.ValidateNodeForTxn(b.hexNodeId, signedTx.From()) { + return errors.New("cannot send transaction from this node") + } return b.eth.txPool.AddLocal(signedTx) } diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 01eeb02760..07ed30de0a 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -633,6 +633,12 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v default: tracer = vm.NewStructLogger(config.LogConfig) } + + // Set the private state to public state if it is not a private message + if msg, ok := message.(core.PrivateMessage); !ok || !api.config.IsQuorum || !msg.IsPrivate() { + privateStateDb = statedb + } + // Run the transaction with tracing enabled. vmenv := vm.NewEVM(vmctx, statedb, privateStateDb, api.config, vm.Config{Debug: true, Tracer: tracer}) diff --git a/eth/backend.go b/eth/backend.go index 245fda7c89..d7af9b20fd 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -206,7 +206,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil, eth.isLocalBlock) eth.miner.SetExtra(makeExtraData(config.MinerExtraData, eth.chainConfig.IsQuorum)) - eth.APIBackend = &EthAPIBackend{eth, nil} + hexNodeId := fmt.Sprintf("%x", crypto.FromECDSAPub(&ctx.NodeKey().PublicKey)[1:]) // Quorum + eth.APIBackend = &EthAPIBackend{eth, nil, hexNodeId} gpoParams := config.GPO if gpoParams.Default == nil { gpoParams.Default = config.MinerGasPrice @@ -257,6 +258,8 @@ func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainCo config.Istanbul.Epoch = chainConfig.Istanbul.Epoch } config.Istanbul.ProposerPolicy = istanbul.ProposerPolicy(chainConfig.Istanbul.ProposerPolicy) + config.Istanbul.Ceil2Nby3Block = chainConfig.Istanbul.Ceil2Nby3Block + return istanbulBackend.New(&config.Istanbul, ctx.NodeKey(), db) } @@ -289,7 +292,7 @@ func (s *Ethereum) APIs() []rpc.API { apis = append(apis, s.engine.APIs(s.BlockChain())...) // Append all the local APIs and return - return append(apis, []rpc.API{ + apis = append(apis, []rpc.API{ { Namespace: "eth", Version: "1.0", @@ -335,6 +338,7 @@ func (s *Ethereum) APIs() []rpc.API { Public: true, }, }...) + return apis } func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { @@ -557,3 +561,7 @@ func (s *Ethereum) Stop() error { close(s.shutdownChan) return nil } + +func (s *Ethereum) CalcGasLimit(block *types.Block) uint64 { + return core.CalcGasLimit(block, s.config.MinerGasFloor, s.config.MinerGasCeil) +} diff --git a/eth/config.go b/eth/config.go index 8b659cabe8..751a659d5d 100644 --- a/eth/config.go +++ b/eth/config.go @@ -49,8 +49,8 @@ var DefaultConfig = Config{ DatabaseCache: 768, TrieCache: 256, TrieTimeout: 60 * time.Minute, - MinerGasFloor: 8000000, - MinerGasCeil: 8000000, + MinerGasFloor: params.MinGasLimit, + MinerGasCeil: params.GenesisGasLimit, MinerGasPrice: big.NewInt(params.GWei), MinerRecommit: 3 * time.Second, diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index f99a450e2d..f3f046f322 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -351,6 +351,8 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode if !atomic.CompareAndSwapInt32(&d.synchronising, 0, 1) { return errBusy } + // changes for permissions. added set sync status to indicate permisssions that node sync has started + types.SetSyncStatus() defer atomic.StoreInt32(&d.synchronising, 0) // Post a user notification of the sync (only once per session) diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 3d4f0d1e59..a86e773e3b 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -244,7 +244,7 @@ func verifyImportEvent(t *testing.T, imported chan *types.Block, arrive bool) { select { case <-imported: t.Fatalf("import invoked") - case <-time.After(10 * time.Millisecond): + case <-time.After(20 * time.Millisecond): } } } diff --git a/eth/handler.go b/eth/handler.go index 5800d7ec06..528e877eea 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -28,6 +28,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -831,20 +833,42 @@ type NodeInfo struct { Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block + Consensus string `json:"consensus"` // Consensus mechanism in use } // NodeInfo retrieves some protocol metadata about the running host node. func (pm *ProtocolManager) NodeInfo() *NodeInfo { currentBlock := pm.blockchain.CurrentBlock() + return &NodeInfo{ Network: pm.networkID, Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()), Genesis: pm.blockchain.Genesis().Hash(), Config: pm.blockchain.Config(), Head: currentBlock.Hash(), + Consensus: pm.getConsensusAlgorithm(), } } +func (pm *ProtocolManager) getConsensusAlgorithm() string { + var consensusAlgo string + if pm.raftMode { // raft does not use consensus interface + consensusAlgo = "raft" + } else { + switch pm.engine.(type) { + case consensus.Istanbul: + consensusAlgo = "istanbul" + case *clique.Clique: + consensusAlgo = "clique" + case *ethash.Ethash: + consensusAlgo = "ethash" + default: + consensusAlgo = "unknown" + } + } + return consensusAlgo +} + func (self *ProtocolManager) FindPeers(targets map[common.Address]bool) map[common.Address]consensus.Peer { m := make(map[common.Address]consensus.Peer) for _, p := range self.peers.Peers() { diff --git a/eth/handler_test.go b/eth/handler_test.go index 5fe16bedcd..da3a779ef3 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -70,6 +70,45 @@ func TestProtocolCompatibility(t *testing.T) { } } +// Tests that correct consensus mechanism details are returned in NodeInfo. +func TestNodeInfo(t *testing.T) { + + // Define the tests to be run + tests := []struct { + consensus string + cliqueConfig *params.CliqueConfig + istanbulConfig *params.IstanbulConfig + raftMode bool + }{ + {"ethash", nil, nil, false}, + {"raft", nil, nil, true}, + {"istanbul", nil, ¶ms.IstanbulConfig{1, 1, big.NewInt(0)}, false}, + {"clique", ¶ms.CliqueConfig{1, 1}, nil, false}, + } + + // Make sure anything we screw up is restored + backup := consensus.EthProtocol.Versions + defer func() { consensus.EthProtocol.Versions = backup }() + + // Try all available consensus mechanisms and check for errors + for i, tt := range tests { + + pm, _, err := newTestProtocolManagerConsensus(tt.consensus, tt.cliqueConfig, tt.istanbulConfig, tt.raftMode) + + if pm != nil { + defer pm.Stop() + } + if err == nil { + pmConsensus := pm.getConsensusAlgorithm() + if tt.consensus != pmConsensus { + t.Errorf("test %d: consensus type error, wanted %v but got %v", i, tt.consensus, pmConsensus) + } + } else { + t.Errorf("test %d: consensus type error %v", i, err) + } + } +} + // Tests that block headers can be retrieved from a remote chain based on user queries. func TestGetBlockHeaders62(t *testing.T) { testGetBlockHeaders(t, 62) } func TestGetBlockHeaders63(t *testing.T) { testGetBlockHeaders(t, 63) } @@ -246,10 +285,10 @@ func testGetBlockBodies(t *testing.T, protocol int) { available []bool // Availability of explicitly requested blocks expected int // Total number of existing blocks to expect }{ - {1, nil, nil, 1}, // A single random block should be retrievable - {10, nil, nil, 10}, // Multiple random blocks should be retrievable - {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable - {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned + {1, nil, nil, 1}, // A single random block should be retrievable + {10, nil, nil, 10}, // Multiple random blocks should be retrievable + {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable + {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned {0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable {0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned diff --git a/eth/helper_test.go b/eth/helper_test.go index 456797cde6..2da1d1fb01 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -27,6 +27,11 @@ import ( "sync" "testing" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -74,6 +79,58 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func return pm, db, nil } +// newTestProtocolManagerConsensus creates a new protocol manager for testing purposes, +// that uses the specified consensus mechanism. +func newTestProtocolManagerConsensus(consensusAlgo string, cliqueConfig *params.CliqueConfig, istanbulConfig *params.IstanbulConfig, raftMode bool) (*ProtocolManager, *ethdb.MemDatabase, error) { + + config := params.QuorumTestChainConfig + config.Clique = cliqueConfig + config.Istanbul = istanbulConfig + + var ( + blocks = 0 + evmux = new(event.TypeMux) + engine consensus.Engine = ethash.NewFaker() + db = ethdb.NewMemDatabase() + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, + } + genesis = gspec.MustCommit(db) + blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil) + ) + chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, nil) + if _, err := blockchain.InsertChain(chain); err != nil { + panic(err) + } + + switch consensusAlgo { + case "raft": + engine = ethash.NewFaker() //raft doesn't use engine, but just mirroring what runtime code does + + case "istanbul": + var istanbul istanbul.Config + config.Istanbul.Epoch = istanbulConfig.Epoch + config.Istanbul.ProposerPolicy = istanbulConfig.ProposerPolicy + + nodeKey, _ := crypto.GenerateKey() + engine = istanbulBackend.New(&istanbul, nodeKey, db) + + case "clique": + engine = clique.New(config.Clique, db) + + default: + engine = ethash.NewFaker() + } + + pm, err := NewProtocolManager(config, 61, DefaultConfig.NetworkId, evmux, &testTxPool{added: nil}, engine, blockchain, db, raftMode) + if err != nil { + return nil, nil, err + } + pm.Start(1000) + return pm, db, nil +} + // newTestProtocolManagerMust creates a new protocol manager for testing purposes, // with the given number of blocks already known, and potential notification // channels for different events. In case of an error, the constructor force- diff --git a/eth/sync.go b/eth/sync.go index daf2c16d63..8f7c4b430c 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -176,6 +176,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) { pHead, pTd := peer.Head() if pTd.Cmp(td) <= 0 { + types.SetSyncStatus() return } // Otherwise try to sync with the downloader @@ -218,14 +219,4 @@ func (pm *ProtocolManager) synchronise(peer *peer) { // more reliably update peers or the local TD state. go pm.BroadcastBlock(head, false) } - atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done - if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 { - // We've completed a sync cycle, notify all peers of new state. This path is - // essential in star-topology networks where a gateway node needs to notify - // all its out-of-date peers of the availability of a new block. This failure - // scenario will most often crop up in private and hackathon networks with - // degenerate connectivity, but it should be healthy for the mainnet too to - // more reliably update peers or the local TD state. - go pm.BroadcastBlock(head, false) - } } diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index f3163e19b3..38a9c80fde 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -24,6 +24,8 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -34,7 +36,8 @@ import ( // Client defines typed wrappers for the Ethereum RPC API. type Client struct { - c *rpc.Client + c *rpc.Client + pc privateTransactionManagerClient // Tessera/Constellation client } // Dial connects a client to the given URL. @@ -52,7 +55,19 @@ func DialContext(ctx context.Context, rawurl string) (*Client, error) { // NewClient creates a client that uses the given RPC client. func NewClient(c *rpc.Client) *Client { - return &Client{c} + return &Client{c, nil} +} + +// Quorum +// +// provides support for private transactions +func (ec *Client) WithPrivateTransactionManager(rawurl string) (*Client, error) { + var err error + ec.pc, err = newPrivateTransactionManagerClient(rawurl) + if err != nil { + return nil, err + } + return ec, nil } func (ec *Client) Close() { @@ -498,12 +513,26 @@ func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64 // // If the transaction was a contract creation use the TransactionReceipt method to get the // contract address after the transaction has been mined. -func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error { +func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction, args bind.PrivateTxArgs) error { data, err := rlp.EncodeToBytes(tx) if err != nil { return err } - return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) + if args.PrivateFor != nil { + return ec.c.CallContext(ctx, nil, "eth_sendRawPrivateTransaction", common.ToHex(data), bind.PrivateTxArgs{PrivateFor: args.PrivateFor}) + } else { + return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) + } +} + +// Quorum +// +// Retrieve encrypted payload hash from the private transaction manager if configured +func (ec *Client) PreparePrivateTransaction(data []byte, privateFrom string) ([]byte, error) { + if ec.pc == nil { + return nil, errors.New("missing private transaction manager client configuration") + } + return ec.pc.storeRaw(data, privateFrom) } func toCallArg(msg ethereum.CallMsg) interface{} { diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 3e8bf974c2..96968b1a76 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -22,6 +22,8 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" ) @@ -150,3 +152,30 @@ func TestToFilterArg(t *testing.T) { }) } } + +func TestClient_PreparePrivateTransaction_whenTypical(t *testing.T) { + testObject := NewClient(nil) + + _, err := testObject.PreparePrivateTransaction([]byte("arbitrary payload"), "arbitrary private from") + + assert.Error(t, err) +} + +func TestClient_PreparePrivateTransaction_whenClientIsConfigured(t *testing.T) { + expectedData := []byte("arbitrary data") + testObject := NewClient(nil) + testObject.pc = &privateTransactionManagerStubClient{expectedData} + + actualData, err := testObject.PreparePrivateTransaction([]byte("arbitrary payload"), "arbitrary private from") + + assert.NoError(t, err) + assert.Equal(t, expectedData, actualData) +} + +type privateTransactionManagerStubClient struct { + expectedData []byte +} + +func (s *privateTransactionManagerStubClient) storeRaw(data []byte, privateFrom string) ([]byte, error) { + return s.expectedData, nil +} diff --git a/ethclient/privateTransactionManagerClient.go b/ethclient/privateTransactionManagerClient.go new file mode 100644 index 0000000000..0d4d6470b0 --- /dev/null +++ b/ethclient/privateTransactionManagerClient.go @@ -0,0 +1,71 @@ +package ethclient + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" +) + +type privateTransactionManagerClient interface { + storeRaw(data []byte, privateFrom string) ([]byte, error) +} + +type privateTransactionManagerDefaultClient struct { + rawurl string + httpClient *http.Client +} + +// Create a new client to interact with private transaction manager via a HTTP endpoint +func newPrivateTransactionManagerClient(endpoint string) (privateTransactionManagerClient, error) { + _, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + return &privateTransactionManagerDefaultClient{ + rawurl: endpoint, + httpClient: &http.Client{}, + }, nil +} + +type storeRawReq struct { + Payload string `json:"payload"` + From string `json:"from,omitempty"` +} + +type storeRawResp struct { + Key string `json:"key"` +} + +func (pc *privateTransactionManagerDefaultClient) storeRaw(data []byte, privateFrom string) ([]byte, error) { + storeRawReq := &storeRawReq{ + Payload: base64.StdEncoding.EncodeToString(data), + From: privateFrom, + } + reqBodyBuf := new(bytes.Buffer) + if err := json.NewEncoder(reqBodyBuf).Encode(storeRawReq); err != nil { + return nil, err + } + resp, err := pc.httpClient.Post(pc.rawurl+"/storeraw", "application/json", reqBodyBuf) + if err != nil { + return nil, fmt.Errorf("unable to invoke /storeraw due to %s", err) + } + defer func() { + _ = resp.Body.Close() + }() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("server returns %s", resp.Status) + } + // parse response + var storeRawResp storeRawResp + if err := json.NewDecoder(resp.Body).Decode(&storeRawResp); err != nil { + return nil, err + } + encryptedPayloadHash, err := base64.StdEncoding.DecodeString(storeRawResp.Key) + if err != nil { + return nil, err + } + return encryptedPayloadHash, nil +} diff --git a/ethclient/privateTransactionManagerClient_test.go b/ethclient/privateTransactionManagerClient_test.go new file mode 100644 index 0000000000..8b4e3b7648 --- /dev/null +++ b/ethclient/privateTransactionManagerClient_test.go @@ -0,0 +1,53 @@ +package ethclient + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + arbitraryBase64Data = "YXJiaXRyYXJ5IGRhdGE=" // = "arbitrary data" +) + +func TestPrivateTransactionManagerClient_storeRaw(t *testing.T) { + // mock tessera client + arbitraryServer := newStoreRawServer() + defer arbitraryServer.Close() + testObject, err := newPrivateTransactionManagerClient(arbitraryServer.URL) + assert.NoError(t, err) + + key, err := testObject.storeRaw([]byte("arbitrary payload"), "arbitrary private from") + + assert.NoError(t, err) + assert.Equal(t, "arbitrary data", string(key)) +} + +func newStoreRawServer() *httptest.Server { + arbitraryResponse := fmt.Sprintf(` +{ + "key": "%s" +} +`, arbitraryBase64Data) + mux := http.NewServeMux() + mux.HandleFunc("/storeraw", func(w http.ResponseWriter, req *http.Request) { + if req.Method == "POST" { + // parse request + var storeRawReq storeRawReq + if err := json.NewDecoder(req.Body).Decode(&storeRawReq); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + // send response + _, _ = fmt.Fprintf(w, "%s", arbitraryResponse) + } else { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + } + + }) + return httptest.NewServer(mux) +} diff --git a/internal/build/util.go b/internal/build/util.go index 195bdb404b..8f1b48f460 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -177,3 +177,27 @@ func ExpandPackagesNoVendor(patterns []string) []string { } return patterns } + +// Read QUORUM_IGNORE_TEST_PACKAGES env and remove from packages +func IgnorePackages(packages []string) []string { + ignore := os.Getenv("QUORUM_IGNORE_TEST_PACKAGES") + if ignore == "" { + return packages + } + ret := make([]string, 0, len(packages)) + ignorePackages := strings.Split(ignore, ",") + + for _, p := range packages { + mustInclude := true + for _, ig := range ignorePackages { + if strings.Index(p, strings.TrimSpace(ig)) == 0 { + mustInclude = false + break + } + } + if mustInclude { + ret = append(ret, p) + } + } + return ret +} diff --git a/internal/build/util_test.go b/internal/build/util_test.go new file mode 100644 index 0000000000..03094a5499 --- /dev/null +++ b/internal/build/util_test.go @@ -0,0 +1,40 @@ +package build + +import ( + "os" + "testing" + + testifyassert "github.com/stretchr/testify/assert" +) + +func TestIgnorePackages_whenTypical(t *testing.T) { + assert := testifyassert.New(t) + + arbitraryPackages := []string{"abc", "xyz/abc"} + + actual := IgnorePackages(arbitraryPackages) + + assert.Equal(arbitraryPackages, actual) +} + +func TestIgnorePackages_whenIgnoreOnePackage(t *testing.T) { + assert := testifyassert.New(t) + + arbitraryPackages := []string{"abc", "xyz/abc"} + assert.NoError(os.Setenv("QUORUM_IGNORE_TEST_PACKAGES", "abc")) + + actual := IgnorePackages(arbitraryPackages) + + assert.Equal([]string{arbitraryPackages[1]}, actual) +} + +func TestIgnorePackages_whenIgnorePackages(t *testing.T) { + assert := testifyassert.New(t) + + arbitraryPackages := []string{"abc", "xyz/abc/opq"} + assert.NoError(os.Setenv("QUORUM_IGNORE_TEST_PACKAGES", "abc, xyz/abc")) + + actual := IgnorePackages(arbitraryPackages) + + assert.Len(actual, 0) +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 8ae253bc92..a8b7452c61 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -29,9 +29,10 @@ import ( "encoding/json" "net/http" - "github.com/davecgh/go-spew/spew" "sync" + "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" @@ -366,6 +367,10 @@ func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArg // Assemble the transaction and sign with the wallet tx := args.toTransaction() + if args.PrivateFor != nil { + tx.SetPrivate() + } + var chainID *big.Int if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { chainID = config.ChainID @@ -392,13 +397,20 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs defer s.nonceLock.UnlockAddr(args.From) } - isPrivate := args.PrivateFor != nil + // Set some sanity defaults and terminate on failure + if err := args.setDefaults(ctx, s.b); err != nil { + return common.Hash{}, err + } + // Assemble the transaction and sign with the wallet + tx := args.toTransaction() + + isPrivate := args.IsPrivate() if isPrivate { data := []byte(*args.Data) if len(data) > 0 { log.Info("sending private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor) - data, err := private.P.Send(data, args.PrivateFrom, args.PrivateFor) + data, err = private.P.Send(data, args.PrivateFrom, args.PrivateFor) log.Info("sent private tx", "data", fmt.Sprintf("%x", data), "privatefrom", args.PrivateFrom, "privatefor", args.PrivateFor) if err != nil { return common.Hash{}, err @@ -407,25 +419,18 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs // zekun: HACK d := hexutil.Bytes(data) args.Data = &d + tx = args.toTransaction() + // set to private before submitting to signer + // this sets the v value to 37 temporarily to indicate a private tx, and to choose the correct signer. + tx.SetPrivate() } - // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, s.b); err != nil { - return common.Hash{}, err - } - // Assemble the transaction and sign with the wallet - tx := args.toTransaction() - - var chainID *big.Int - if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) && !isPrivate { - chainID = config.ChainID - } - signed, err := wallet.SignTxWithPassphrase(account, passwd, tx, chainID) + signed, err := wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) if err != nil { log.Warn("Failed transaction send attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) return common.Hash{}, err } - return submitTransaction(ctx, s.b, signed, isPrivate) + return submitTransaction(ctx, s.b, signed) } // SignTransaction will create a transaction from the given arguments and @@ -1150,6 +1155,16 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx cont // GetTransactionCount returns the number of transactions the given address has sent for the given block number func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { + // Ask transaction pool for the nonce which includes pending transactions + if blockNr == rpc.PendingBlockNumber { + nonce, err := s.b.GetPoolNonce(ctx, address) + if err != nil { + return nil, err + } + return (*hexutil.Uint64)(&nonce), nil + } + + // Resolve block number and use its state to ask for the nonce state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) if state == nil || err != nil { return nil, err @@ -1238,6 +1253,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha return fields, nil } +// quorum: if signing a private TX set with tx.SetPrivate() before calling this method. // sign is a helper function that signs a transaction with the private key of the given address. func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { // Look up the wallet containing the requested signer @@ -1249,11 +1265,10 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti } // Request the wallet to sign the transaction var chainID *big.Int - isQuorum := tx.IsPrivate() if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) && !tx.IsPrivate() { chainID = config.ChainID } - return wallet.SignTx(account, tx, chainID, isQuorum) + return wallet.SignTx(account, tx, chainID) } // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. @@ -1276,6 +1291,10 @@ type SendTxArgs struct { //End-Quorum } +func (s SendTxArgs) IsPrivate() bool { + return s.PrivateFor != nil +} + // SendRawTxArgs represents the arguments to submit a new signed private transaction into the transaction pool. type SendRawTxArgs struct { PrivateFor []string `json:"privateFor"` @@ -1325,17 +1344,19 @@ func (args *SendTxArgs) toTransaction() *types.Transaction { return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) } +// TODO: this submits a signed transaction, if it is a signed private transaction that should already be recorded in the tx. // submitTransaction is a helper function that submits tx to txPool and logs a message. -func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, isPrivate bool) (common.Hash, error) { - if isPrivate { - tx.SetPrivate() - } - +func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { if err := b.SendTx(ctx, tx); err != nil { return common.Hash{}, err } if tx.To() == nil { - signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) + var signer types.Signer + if tx.IsPrivate() { + signer = types.QuorumPrivateTxSigner{} + } else { + signer = types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) + } from, err := types.Sender(signer, tx) if err != nil { return common.Hash{}, err @@ -1369,7 +1390,7 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen defer s.nonceLock.UnlockAddr(args.From) } - isPrivate := args.PrivateFor != nil + isPrivate := args.IsPrivate() var data []byte if isPrivate { if args.Data != nil { @@ -1401,15 +1422,19 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen tx := args.toTransaction() var chainID *big.Int - isQuorum := tx.IsPrivate() if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) && !isPrivate { chainID = config.ChainID } - signed, err := wallet.SignTx(account, tx, chainID, isQuorum) + + if isPrivate { + tx.SetPrivate() + } + signed, err := wallet.SignTx(account, tx, chainID) if err != nil { return common.Hash{}, err } - return submitTransaction(ctx, s.b, signed, isPrivate) + return submitTransaction(ctx, s.b, signed) + } // SendRawTransaction will add the signed transaction to the transaction pool. @@ -1419,7 +1444,7 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod if err := rlp.DecodeBytes(encodedTx, tx); err != nil { return common.Hash{}, err } - return submitTransaction(ctx, s.b, tx, tx.IsPrivate()) + return submitTransaction(ctx, s.b, tx) } // SendRawPrivateTransaction will add the signed transaction to the transaction pool. @@ -1432,7 +1457,7 @@ func (s *PublicTransactionPoolAPI) SendRawPrivateTransaction(ctx context.Context } txHash := []byte(tx.Data()) - isPrivate := args.PrivateFor != nil + isPrivate := (args.PrivateFor != nil) && tx.IsPrivate() if isPrivate { if len(txHash) > 0 { @@ -1447,8 +1472,7 @@ func (s *PublicTransactionPoolAPI) SendRawPrivateTransaction(ctx context.Context } else { return common.Hash{}, fmt.Errorf("transaction is not private") } - - return submitTransaction(ctx, s.b, tx, isPrivate) + return submitTransaction(ctx, s.b, tx) } // Sign calculates an ECDSA signature for: @@ -1498,13 +1522,17 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen if err := args.setDefaults(ctx, s.b); err != nil { return nil, err } - tx, err := s.sign(args.From, args.toTransaction()) + + toSign := args.toTransaction() + + if args.PrivateFor != nil { + toSign.SetPrivate() + } + + tx, err := s.sign(args.From, toSign) if err != nil { return nil, err } - if args.PrivateFor != nil { - tx.SetPrivate() - } data, err := rlp.EncodeToBytes(tx) if err != nil { return nil, err @@ -1556,7 +1584,9 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr for _, p := range pending { var signer types.Signer = types.HomesteadSigner{} - if p.Protected() && !p.IsPrivate() { + if p.IsPrivate() { + signer = types.QuorumPrivateTxSigner{} + } else if p.Protected() { signer = types.NewEIP155Signer(p.ChainId()) } wantSigHash := signer.Hash(matchTx) @@ -1570,10 +1600,10 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr sendArgs.Gas = gasLimit } newTx := sendArgs.toTransaction() - if len(sendArgs.PrivateFor) > 0 { + // set v param to 37 to indicate private tx before submitting to the signer. + if sendArgs.PrivateFor != nil { newTx.SetPrivate() } - signedTx, err := s.sign(sendArgs.From, newTx) if err != nil { return common.Hash{}, err @@ -1754,12 +1784,12 @@ func (s *PublicTransactionPoolAPI) send(ctx context.Context, asyncArgs AsyncSend buf := new(bytes.Buffer) err := json.NewEncoder(buf).Encode(resultResponse) if err != nil { - log.Info("Error encoding callback JSON: %v", err) + log.Info("Error encoding callback JSON", "err", err.Error()) return } _, err = http.Post(asyncArgs.CallbackUrl, "application/json", buf) if err != nil { - log.Info("Error sending callback: %v", err) + log.Info("Error sending callback", "err", err.Error()) return } } diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go index 146750dac0..9c7ad16d18 100644 --- a/internal/guide/guide_test.go +++ b/internal/guide/guide_test.go @@ -85,7 +85,7 @@ func TestAccountManagement(t *testing.T) { if err := ks.Unlock(signer, "Signer password"); err != nil { t.Fatalf("Failed to unlock account: %v", err) } - if _, err := ks.SignTx(signer, tx, chain, false); err != nil { + if _, err := ks.SignTx(signer, tx, chain); err != nil { t.Fatalf("Failed to sign with unlocked account: %v", err) } if err := ks.Lock(signer.Address); err != nil { @@ -95,7 +95,7 @@ func TestAccountManagement(t *testing.T) { if err := ks.TimedUnlock(signer, "Signer password", time.Second); err != nil { t.Fatalf("Failed to time unlock account: %v", err) } - if _, err := ks.SignTx(signer, tx, chain, false); err != nil { + if _, err := ks.SignTx(signer, tx, chain); err != nil { t.Fatalf("Failed to sign with time unlocked account: %v", err) } } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index f7f4915d80..a0e9eae0be 100755 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -18,21 +18,22 @@ package web3ext var Modules = map[string]string{ - "admin": Admin_JS, - "chequebook": Chequebook_JS, - "clique": Clique_JS, - "ethash": Ethash_JS, - "debug": Debug_JS, - "eth": Eth_JS, - "miner": Miner_JS, - "net": Net_JS, - "personal": Personal_JS, - "rpc": RPC_JS, - "shh": Shh_JS, - "swarmfs": SWARMFS_JS, - "txpool": TxPool_JS, - "raft": Raft_JS, - "istanbul": Istanbul_JS, + "admin": Admin_JS, + "chequebook": Chequebook_JS, + "clique": Clique_JS, + "ethash": Ethash_JS, + "debug": Debug_JS, + "eth": Eth_JS, + "miner": Miner_JS, + "net": Net_JS, + "personal": Personal_JS, + "rpc": RPC_JS, + "shh": Shh_JS, + "swarmfs": SWARMFS_JS, + "txpool": TxPool_JS, + "raft": Raft_JS, + "istanbul": Istanbul_JS, + "quorumPermission": QUORUM_NODE_JS, } const Chequebook_JS = ` @@ -500,7 +501,21 @@ web3._extend({ call: 'eth_storageRoot', params: 2, inputFormatter: [web3._extend.formatters.inputAddressFormatter, null] - }) + }), + // QUORUM + new web3._extend.Method({ + name: 'sendTransactionAsync', + call: 'eth_sendTransactionAsync', + params: 1, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'getQuorumPayload', + call: 'eth_getQuorumPayload', + params: 1, + inputFormatter: [null] + }), + // END-QUORUM ], properties: [ new web3._extend.Property({ @@ -724,6 +739,16 @@ web3._extend({ call: 'raft_addPeer', params: 1 }), + new web3._extend.Method({ + name: 'addLearner', + call: 'raft_addLearner', + params: 1 + }), + new web3._extend.Method({ + name: 'promoteToPeer', + call: 'raft_promoteToPeer', + params: 1 + }), new web3._extend.Method({ name: 'removePeer', call: 'raft_removePeer', @@ -741,6 +766,149 @@ web3._extend({ }) ` +const QUORUM_NODE_JS = ` +web3._extend({ + property: 'quorumPermission', + methods: + [ + new web3._extend.Method({ + name: 'addOrg', + call: 'quorumPermission_addOrg', + params: 4, + inputFormatter: [null,null,web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'approveOrg', + call: 'quorumPermission_approveOrg', + params: 4, + inputFormatter: [null,null,web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'addSubOrg', + call: 'quorumPermission_addSubOrg', + params: 4, + inputFormatter: [null,null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'updateOrgStatus', + call: 'quorumPermission_updateOrgStatus', + params: 3, + inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'approveOrgStatus', + call: 'quorumPermission_approveOrgStatus', + params: 3, + inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'addNode', + call: 'quorumPermission_addNode', + params: 3, + inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'updateNodeStatus', + call: 'quorumPermission_updateNodeStatus', + params: 4, + inputFormatter: [null,null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'assignAdminRole', + call: 'quorumPermission_assignAdminRole', + params: 4, + inputFormatter: [null,web3._extend.formatters.inputAddressFormatter,null, web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'approveAdminRole', + call: 'quorumPermission_approveAdminRole', + params: 3, + inputFormatter: [null, web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'addNewRole', + call: 'quorumPermission_addNewRole', + params: 6, + inputFormatter: [null,null,null,null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'removeRole', + call: 'quorumPermission_removeRole', + params: 3, + inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'addAccountToOrg', + call: 'quorumPermission_addAccountToOrg', + params: 4, + inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'changeAccountRole', + call: 'quorumPermission_changeAccountRole', + params: 4, + inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'updateAccountStatus', + call: 'quorumPermission_updateAccountStatus', + params: 4, + inputFormatter: [null, web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'recoverBlackListedNode', + call: 'quorumPermission_recoverBlackListedNode', + params: 3, + inputFormatter: [null, null, web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'approveBlackListedNodeRecovery', + call: 'quorumPermission_approveBlackListedNodeRecovery', + params: 3, + inputFormatter: [null, null, web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'recoverBlackListedAccount', + call: 'quorumPermission_recoverBlackListedAccount', + params: 3, + inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'approveBlackListedAccountRecovery', + call: 'quorumPermission_approveBlackListedAccountRecovery', + params: 3, + inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'getOrgDetails', + call: 'quorumPermission_getOrgDetails', + params: 1, + inputFormatter: [null] + }), + + ], + properties: + [ + new web3._extend.Property({ + name: 'orgList', + getter: 'quorumPermission_orgList' + }), + new web3._extend.Property({ + name: 'nodeList', + getter: 'quorumPermission_nodeList' + }), + new web3._extend.Property({ + name: 'roleList', + getter: 'quorumPermission_roleList' + }), + new web3._extend.Property({ + name: 'acctList', + getter: 'quorumPermission_acctList' + }), + ] +}) +` + const Istanbul_JS = ` web3._extend({ property: 'istanbul', @@ -777,7 +945,19 @@ web3._extend({ name: 'discard', call: 'istanbul_discard', params: 1 - }) + }), + + new web3._extend.Method({ + name: 'getSignersFromBlock', + call: 'istanbul_getSignersFromBlock', + params: 1, + inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter] + }), + new web3._extend.Method({ + name: 'getSignersFromBlockByHash', + call: 'istanbul_getSignersFromBlockByHash', + params: 1 + }), ], properties: [ @@ -785,6 +965,10 @@ web3._extend({ name: 'candidates', getter: 'istanbul_candidates' }), + new web3._extend.Property({ + name: 'nodeAddress', + getter: 'istanbul_nodeAddress' + }), ] }); ` diff --git a/log/emit_checkpoint.go b/log/emit_checkpoint.go index cf7262254e..25b658ddcf 100644 --- a/log/emit_checkpoint.go +++ b/log/emit_checkpoint.go @@ -5,6 +5,7 @@ const ( TxAccepted = "TX-ACCEPTED" BecameMinter = "BECAME-MINTER" BecameVerifier = "BECAME-VERIFIER" + BecameLearner = "BECAME-LEARNER" BlockCreated = "BLOCK-CREATED" BlockVotingStarted = "BLOCK-VOTING-STARTED" ) diff --git a/miner/miner.go b/miner/miner.go index 41d69f9bc3..565df529c6 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -28,10 +28,10 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/ethdb" ) // Backend wraps all methods required for mining. diff --git a/miner/worker.go b/miner/worker.go index 93b897d269..42cea0ae2a 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -544,7 +544,10 @@ func (w *worker) taskLoop() { w.pendingMu.Lock() w.pendingTasks[w.engine.SealHash(task.block.Header())] = task w.pendingMu.Unlock() - go w.seal(task.block, stopCh) + + if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil { + log.Warn("Block sealing failed", "err", err) + } case <-w.exitCh: interrupt() return @@ -552,12 +555,6 @@ func (w *worker) taskLoop() { } } -func (w *worker) seal(b *types.Block, stop <-chan struct{}) { - if err := w.engine.Seal(w.chain, b, w.resultCh, stop); err != nil { - log.Warn("Block sealing failed", "err", err) - } -} - // resultLoop is a standalone goroutine to handle sealing result submitting // and flush relative data to the database. func (w *worker) resultLoop() { @@ -585,39 +582,38 @@ func (w *worker) resultLoop() { } // Different block could share same sealhash, deep copy here to prevent write-write conflict. var logs []*types.Log - work := w.current - for _, receipt := range append(work.receipts, work.privateReceipts...) { + for _, receipt := range append(task.receipts, task.privateReceipts...) { // Update the block hash in all logs since it is now available and not when the // receipt/log of individual transactions were created. for _, log := range receipt.Logs { log.BlockHash = hash } + logs = append(logs, receipt.Logs...) } - for _, log := range append(work.state.Logs(), work.privateState.Logs()...) { - log.BlockHash = hash + // write private transactions + privateStateRoot, err := task.privateState.Commit(w.config.IsEIP158(block.Number())) + if err != nil { + log.Error("Failed committing private state root", "err", err) + continue } - - // write private transacions - privateStateRoot, _ := work.privateState.Commit(w.config.IsEIP158(block.Number())) - core.WritePrivateStateRoot(w.eth.ChainDb(), block.Root(), privateStateRoot) - allReceipts := mergeReceipts(work.receipts, work.privateReceipts) + if err := core.WritePrivateStateRoot(w.eth.ChainDb(), block.Root(), privateStateRoot); err != nil { + log.Error("Failed writing private state root", "err", err) + continue + } + allReceipts := mergeReceipts(task.receipts, task.privateReceipts) // Commit block and state to database. - w.mu.Lock() - stat, err := w.chain.WriteBlockWithState(block, allReceipts, work.state, nil) - w.mu.Unlock() + stat, err := w.chain.WriteBlockWithState(block, allReceipts, task.state, nil) if err != nil { - log.Error("Failed writWriteBlockAndStating block to chain", "err", err) + log.Error("Failed writing block to chain", "err", err) continue } - - if err := core.WritePrivateBlockBloom(w.eth.ChainDb(), block.NumberU64(), work.privateReceipts); err != nil { + if err := core.WritePrivateBlockBloom(w.eth.ChainDb(), block.NumberU64(), task.privateReceipts); err != nil { log.Error("Failed writing private block bloom", "err", err) continue } - log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, "elapsed", common.PrettyDuration(time.Since(task.createdAt))) @@ -625,8 +621,6 @@ func (w *worker) resultLoop() { w.mux.Post(core.NewMinedBlockEvent{Block: block}) var events []interface{} - logs = append(work.state.Logs(), work.privateState.Logs()...) - switch stat { case core.CanonStatTy: events = append(events, core.ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) @@ -1023,8 +1017,8 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st privateReceipts := make([]*types.Receipt, len(w.current.privateReceipts)) for i, l := range w.current.privateReceipts { - receipts[i] = new(types.Receipt) - *receipts[i] = *l + privateReceipts[i] = new(types.Receipt) + *privateReceipts[i] = *l } s := w.current.state.Copy() diff --git a/miner/worker_test.go b/miner/worker_test.go index bda4f17c3e..3b1c1568cc 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -225,7 +225,7 @@ func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consens for i := 0; i < 2; i += 1 { select { case <-taskCh: - case <-time.NewTimer(time.Second).C: + case <-time.NewTimer(2 * time.Second).C: t.Error("new task timeout") } } diff --git a/mkdocs.yml b/mkdocs.yml index 669f426420..cf02102c06 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,19 +12,38 @@ repo_url: https://github.com/jpmorganchase/quorum nav: - Getting Started: - - Setup Overview & Quickstart: Getting Started/Setup Overview & Quickstart.md - - Getting Started From Scratch: Getting Started/Getting-Started-From-Scratch.md - - Quorum Examples: - - Overview: Getting Started/Quorum-Examples.md - - 7 Nodes Example: Getting Started/7Nodes.md + - Overview: Getting Started/Getting Started Overview.md + - Installing: Getting Started/Installing.md + - Examples: Getting Started/Quorum-Examples.md + - Creating a Network From Scratch: Getting Started/Creating-A-Network-From-Scratch.md - Running Quorum: Getting Started/running.md + - Quorum API: Getting Started/api.md - Consensus: - Consensus: Consensus/Consensus.md - Raft: Consensus/raft.md - - Istanbul: Consensus/istanbul-rpc-api.md + - Istanbul BFT: + - Consensus/ibft/istanbul-rpc-api.md + - Consensus/ibft/ibft-parameters.md - Transaction Processing: Transaction Processing/Transaction Processing.md - - Security: - - Security & Permissioning: Security/Security & Permissioning.md + - Security Framework: + - Overview: Security/Framework/Overview.md + - Quorum Network: + - Consortium: Security/Framework/Quorum Network Security/Consortium.md + - Quorum Node: + - Overview: Security/Framework/Quorum Network Security/Node.md + - Permissioning: + - Network Permissioning: Security/Framework/Quorum Network Security/Nodes/Permissioning/Network Permissioning.md + - Transaction Manager: Security/Framework/Quorum Network Security/Transaction Manager.md + - Operational Considerations: Security/Framework/Quorum Network Security/Opertional Considerations.md + - Decentralized App: + - Frontend: Security/Framework/Decentralized Application/Frontend Components.md + - Smart Contracts: Security/Framework/Decentralized Application/Smart Contracts Security.md + - Permissioning: + - Overview: Permissioning/Overview.md + - Design: Permissioning/Contract Design.md + - Setup: Permissioning/setup.md + - APIs: Permissioning/Permissioning apis.md + - Usage: Permissioning/Usage.md - Privacy: - Tessera: - What is Tessera: Privacy/Tessera/Tessera.md @@ -52,6 +71,19 @@ nav: - How it works: Privacy/Constellation/How constellation works.md - Sample Configuration: Privacy/Constellation/Sample Configuration.md - Running Constellation: Privacy/Constellation/Installation & Running.md + - Cakeshop: + - Overview: Cakeshop/Overview.md + - Getting Started: Cakeshop/Getting started.md + - Cakeshop FAQ: Cakeshop/Cakeshop FAQ.md + - Remix Plugin: + - Overview: RemixPlugin/Overview.md + - Getting Started: RemixPlugin/Getting started.md + - Quorum Features: + - DNS: Features/dns.md + - How-To Guides: + - Adding new nodes: How-To-Guides/adding_nodes.md + - Adding IBFT validators: How-To-Guides/add_ibft_validator.md + - Product Roadmap: roadmap.md - FAQ: FAQ.md theme: @@ -62,6 +94,7 @@ theme: code: 'Roboto Mono' language: 'en' logo: 'images/logo.png' + favicon: 'images/logo-48x48.png' extra_css: - 'theme/assets/stylesheets/extra.css' diff --git a/mobile/accounts.go b/mobile/accounts.go index 2ddff93e69..4d979bffff 100644 --- a/mobile/accounts.go +++ b/mobile/accounts.go @@ -120,7 +120,7 @@ func (ks *KeyStore) SignTx(account *Account, tx *Transaction, chainID *BigInt) ( if chainID == nil { // Null passed from mobile app chainID = new(BigInt) } - signed, err := ks.keystore.SignTx(account.account, tx.tx, chainID.bigint, false) + signed, err := ks.keystore.SignTx(account.account, tx.tx, chainID.bigint) if err != nil { return nil, err } diff --git a/mobile/ethclient.go b/mobile/ethclient.go index 662125c4ad..32cd8b199f 100644 --- a/mobile/ethclient.go +++ b/mobile/ethclient.go @@ -21,6 +21,8 @@ package geth import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" ) @@ -312,5 +314,5 @@ func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (gas int64, _ // If the transaction was a contract creation use the TransactionReceipt method to get the // contract address after the transaction has been mined. func (ec *EthereumClient) SendTransaction(ctx *Context, tx *Transaction) error { - return ec.client.SendTransaction(ctx.context, tx.tx) + return ec.client.SendTransaction(ctx.context, tx.tx, bind.PrivateTxArgs{}) } diff --git a/node/config.go b/node/config.go index 8d045a1677..b42f979b75 100644 --- a/node/config.go +++ b/node/config.go @@ -25,6 +25,8 @@ import ( "runtime" "strings" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/usbwallet" @@ -406,6 +408,21 @@ func (c *Config) AccountConfig() (int, int, string, error) { return scryptN, scryptP, keydir, err } +// Quorum +// +// check if smart-contract-based permissioning is enabled by reading `--permissioned` flag and checking permission config file +func (c *Config) IsPermissionEnabled() bool { + if c.EnableNodePermission { + fullPath := filepath.Join(c.DataDir, params.PERMISSION_MODEL_CONFIG) + if _, err := os.Stat(fullPath); err != nil { + log.Warn(fmt.Sprintf("%s file is missing. Smart-contract-based permission service will be disabled", params.PERMISSION_MODEL_CONFIG), "error", err) + return false + } + return true + } + return false +} + func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { scryptN, scryptP, keydir, err := conf.AccountConfig() var ephemeral string diff --git a/node/config_test.go b/node/config_test.go index b81d3d6120..a7857ff96d 100644 --- a/node/config_test.go +++ b/node/config_test.go @@ -20,10 +20,14 @@ import ( "bytes" "io/ioutil" "os" + "path" "path/filepath" "runtime" "testing" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/assert" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p" ) @@ -148,3 +152,45 @@ func TestNodeKeyPersistency(t *testing.T) { t.Fatalf("ephemeral node key persisted to disk") } } + +// Quorum +// +func TestConfig_IsPermissionEnabled_whenTypical(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "q-") + if err != nil { + t.Fatal(err) + } + defer func() { + _ = os.RemoveAll(tmpdir) + }() + if err := ioutil.WriteFile(path.Join(tmpdir, params.PERMISSION_MODEL_CONFIG), []byte("foo"), 0644); err != nil { + t.Fatal(err) + } + testObject := &Config{ + EnableNodePermission: true, + DataDir: tmpdir, + } + + assert.True(t, testObject.IsPermissionEnabled()) +} + +// Quorum +// +func TestConfig_IsPermissionEnabled_whenPermissionedFlagIsFalse(t *testing.T) { + testObject := &Config{ + EnableNodePermission: false, + } + + assert.False(t, testObject.IsPermissionEnabled()) +} + +// Quorum +// +func TestConfig_IsPermissionEnabled_whenPermissionConfigIsNotAvailable(t *testing.T) { + testObject := &Config{ + EnableNodePermission: true, + DataDir: os.TempDir(), + } + + assert.False(t, testObject.IsPermissionEnabled()) +} diff --git a/node/node.go b/node/node.go index 5b7f38826d..90984d7f7a 100644 --- a/node/node.go +++ b/node/node.go @@ -17,6 +17,7 @@ package node import ( + "crypto/ecdsa" "errors" "fmt" "net" @@ -292,7 +293,7 @@ func (n *Node) startInProc(apis []rpc.API) error { n.log.Debug("InProc registered", "service", api.Service, "namespace", api.Namespace) } n.inprocHandler = handler - return nil + return n.eventmux.Post(rpc.InProcServerReadyEvent{}) } // stopInProc terminates the in-process RPC endpoint. @@ -528,6 +529,20 @@ func (n *Node) Service(service interface{}) error { return ErrServiceUnknown } +// Quorum +// +// delegate call to node.Config +func (n *Node) IsPermissionEnabled() bool { + return n.config.IsPermissionEnabled() +} + +// Quorum +// +// delegate call to node.Config +func (n *Node) GetNodeKey() *ecdsa.PrivateKey { + return n.config.NodeKey() +} + // DataDir retrieves the current datadir used by the protocol stack. // Deprecated: No files should be stored in this directory, use InstanceDir instead. func (n *Node) DataDir() string { diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go index 84c3dd16f4..7c0cc75236 100644 --- a/p2p/discover/udp_test.go +++ b/p2p/discover/udp_test.go @@ -311,6 +311,7 @@ func TestUDP_findnodeMultiReply(t *testing.T) { rpclist := make([]rpcNode, len(list)) for i := range list { rpclist[i] = nodeToRPC(list[i]) + list[i] = wrapNode(enode.NewV4(list[i].Pubkey(), list[i].IP(), list[i].TCP(), list[i].UDP(), 0)) } test.packetIn(nil, neighborsPacket, &neighbors{Expiration: futureExp, Nodes: rpclist[:2]}) test.packetIn(nil, neighborsPacket, &neighbors{Expiration: futureExp, Nodes: rpclist[2:]}) diff --git a/p2p/discv5/node_test.go b/p2p/discv5/node_test.go index ce4ad9e4d4..c231345db2 100644 --- a/p2p/discv5/node_test.go +++ b/p2p/discv5/node_test.go @@ -152,7 +152,7 @@ func TestParseNode(t *testing.T) { if err == nil { t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError) continue - } else if err.Error() != test.wantError { + } else if !strings.Contains(err.Error(), test.wantError) { t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError) continue } diff --git a/p2p/enode/node.go b/p2p/enode/node.go index a0645b324e..dced1b6ff0 100644 --- a/p2p/enode/node.go +++ b/p2p/enode/node.go @@ -21,6 +21,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/ethereum/go-ethereum/log" "math/bits" "math/rand" "net" @@ -70,11 +71,36 @@ func (n *Node) Load(k enr.Entry) error { // IP returns the IP address of the node. func (n *Node) IP() net.IP { + // QUORUM + // no host is set, so use the IP directly + if n.Host() == "" { + return n.loadIP() + } + // attempt to look up IP addresses if host is a FQDN + lookupIPs, err := net.LookupIP(n.Host()) + if err != nil { + log.Debug("hostname couldn't resolve, using IP instead", "hostname", n.Host(), "err", err.Error()) + return n.loadIP() + } + // set to first ip by default + return lookupIPs[0] + // END QUORUM +} + +func (n *Node) loadIP() net.IP { var ip net.IP n.Load((*enr.IP)(&ip)) return ip } +// Quorum +func (n *Node) Host() string { + var hostname string + n.Load((*enr.Hostname)(&hostname)) + return hostname +} +// End-Quorum + // UDP returns the UDP port of the node. func (n *Node) UDP() int { var port enr.UDP diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index c928f5c81f..81cdf664ef 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -84,6 +84,12 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp, raftPort int) *Node { if ip != nil { r.Set(enr.IP(ip)) } + return newV4(pubkey, r, tcp, udp, raftPort) +} + +// broken out from `func NewV4` (above) same in upstream go-ethereum, but taken out +// to avoid code duplication b/t NewV4 and NewV4Hostname +func newV4(pubkey *ecdsa.PublicKey, r enr.Record, tcp, udp, raftPort int) *Node { if udp != 0 { r.Set(enr.UDP(udp)) } @@ -91,7 +97,7 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp, raftPort int) *Node { r.Set(enr.TCP(tcp)) } - if raftPort != 0 { + if raftPort != 0 { // Quorum r.Set(enr.RaftPort(raftPort)) } @@ -103,10 +109,24 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp, raftPort int) *Node { return n } +// Quorum + +// NewV4Hostname creates a node from discovery v4 node information. The record +// contained in the node has a zero-length signature. It sets the hostname of +// the node instead of the IP address. +func NewV4Hostname(pubkey *ecdsa.PublicKey, hostname string, tcp, udp, raftPort int) *Node { + var r enr.Record + if hostname != "" { + r.Set(enr.Hostname(hostname)) + } + return newV4(pubkey, r, tcp, udp, raftPort) +} + +// End-Quorum + func parseComplete(rawurl string) (*Node, error) { var ( id *ecdsa.PublicKey - ip net.IP tcpPort, udpPort uint64 ) u, err := url.Parse(rawurl) @@ -123,20 +143,8 @@ func parseComplete(rawurl string) (*Node, error) { if id, err = parsePubkey(u.User.String()); err != nil { return nil, fmt.Errorf("invalid node ID (%v)", err) } - // Parse the IP address. - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - return nil, fmt.Errorf("invalid host: %v", err) - } - if ip = net.ParseIP(host); ip == nil { - return nil, errors.New("invalid IP address") - } - // Ensure the IP is 4 bytes long for IPv4 addresses. - if ipv4 := ip.To4(); ipv4 != nil { - ip = ipv4 - } // Parse the port numbers. - if tcpPort, err = strconv.ParseUint(port, 10, 16); err != nil { + if tcpPort, err = strconv.ParseUint(u.Port(), 10, 16); err != nil { return nil, errors.New("invalid port") } udpPort = tcpPort @@ -150,17 +158,19 @@ func parseComplete(rawurl string) (*Node, error) { var node *Node + // Quorum if qv.Get("raftport") != "" { raftPort, err := strconv.ParseUint(qv.Get("raftport"), 10, 16) if err != nil { return nil, errors.New("invalid raftport in query") } - node = NewV4(id, ip, int(tcpPort), int(udpPort), int(raftPort)) + node = NewV4Hostname(id, u.Hostname(), int(tcpPort), int(udpPort), int(raftPort)) } else { - node = NewV4(id, ip, int(tcpPort), int(udpPort), 0) + node = NewV4Hostname(id, u.Hostname(), int(tcpPort), int(udpPort), 0) } - return node, nil + // End-Quorum + return node, nil } func HexPubkey(h string) (*ecdsa.PublicKey, error) { diff --git a/p2p/enode/urlv4_test.go b/p2p/enode/urlv4_test.go index f6b9278c1a..9b76bb9ecb 100644 --- a/p2p/enode/urlv4_test.go +++ b/p2p/enode/urlv4_test.go @@ -20,7 +20,6 @@ import ( "bytes" "crypto/ecdsa" "math/big" - "net" "reflect" "strings" "testing" @@ -41,10 +40,6 @@ var parseNodeTests = []struct { wantError: `invalid node ID (wrong length, want 128 hex chars)`, }, // Complete nodes with IP address. - { - rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3", - wantError: `invalid IP address`, - }, { rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo", wantError: `invalid port`, @@ -55,9 +50,9 @@ var parseNodeTests = []struct { }, { rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150", - wantResult: NewV4( + wantResult: NewV4Hostname( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), - net.IP{0x7f, 0x0, 0x0, 0x1}, + "127.0.0.1", 52150, 52150, 0, @@ -65,9 +60,9 @@ var parseNodeTests = []struct { }, { rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150", - wantResult: NewV4( + wantResult: NewV4Hostname( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), - net.ParseIP("::"), + "::", 52150, 52150, 0, @@ -75,9 +70,9 @@ var parseNodeTests = []struct { }, { rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150", - wantResult: NewV4( + wantResult: NewV4Hostname( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), - net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), + "2001:db8:3c4d:15::abcd:ef12", 52150, 52150, 0, @@ -85,9 +80,9 @@ var parseNodeTests = []struct { }, { rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334", - wantResult: NewV4( + wantResult: NewV4Hostname( hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), - net.IP{0x7f, 0x0, 0x0, 0x1}, + "127.0.0.1", 52150, 22334, 0, @@ -133,13 +128,26 @@ func hexPubkey(h string) *ecdsa.PublicKey { } func TestParseNode(t *testing.T) { - for _, test := range parseNodeTests { + extraTests := []struct { + rawurl string + wantError string + wantResult *Node + }{ + { + rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3", + wantResult: NewV4Hostname(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), "hostname", 3, 3, 0, ), + }, + } + + testNodes := append(parseNodeTests, extraTests...) + + for _, test := range testNodes { n, err := ParseV4(test.rawurl) if test.wantError != "" { if err == nil { t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError) continue - } else if err.Error() != test.wantError { + } else if !strings.Contains(err.Error(), test.wantError) { t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError) continue } diff --git a/p2p/enr/entries.go b/p2p/enr/entries.go index ceb4b1017b..ae7c7f6b11 100644 --- a/p2p/enr/entries.go +++ b/p2p/enr/entries.go @@ -82,6 +82,10 @@ type RaftPort uint16 func (v RaftPort) ENRKey() string { return "raftport" } +type Hostname string + +func (v Hostname) ENRKey() string { return "hostname" } + // EncodeRLP implements rlp.Encoder. func (v IP) EncodeRLP(w io.Writer) error { if ip4 := net.IP(v).To4(); ip4 != nil { diff --git a/p2p/peer_error.go b/p2p/peer_error.go index ab61bfef06..f44c5b4c50 100644 --- a/p2p/peer_error.go +++ b/p2p/peer_error.go @@ -26,9 +26,22 @@ const ( errInvalidMsg ) +// Quorum +// +// Constants for peer connection errors +const ( + // When permissioning is enabled, and node is not permissioned in the network + errPermissionDenied = iota + 100 + // Unauthorized node joining existing raft cluster + errNotInRaftCluster +) + var errorToString = map[int]string{ errInvalidMsgCode: "invalid message code", errInvalidMsg: "invalid message", + // Quorum + errPermissionDenied: "permission denied", + errNotInRaftCluster: "not in raft cluster", } type peerError struct { diff --git a/p2p/permissions.go b/p2p/permissions.go index 1941b6c822..334310b8e3 100644 --- a/p2p/permissions.go +++ b/p2p/permissions.go @@ -5,21 +5,22 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" ) const ( - NODE_NAME_LENGTH = 32 - PERMISSIONED_CONFIG = "permissioned-nodes.json" + NODE_NAME_LENGTH = 32 ) +//TODO update this based on permission changes // check if a given node is permissioned to connect to the change func isNodePermissioned(nodename string, currentNode string, datadir string, direction string) bool { - var permissionedList []string - nodes := parsePermissionedNodes(datadir) + nodes := ParsePermissionedNodes(datadir) for _, v := range nodes { permissionedList = append(permissionedList, v.ID().String()) } @@ -28,6 +29,10 @@ func isNodePermissioned(nodename string, currentNode string, datadir string, dir for _, v := range permissionedList { if v == nodename { log.Debug("isNodePermissioned", "connection", direction, "nodename", nodename[:NODE_NAME_LENGTH], "ALLOWED-BY", currentNode[:NODE_NAME_LENGTH]) + // check if the node is blacklisted + if isNodeBlackListed(nodename, datadir) { + return false + } return true } } @@ -38,11 +43,11 @@ func isNodePermissioned(nodename string, currentNode string, datadir string, dir //this is a shameless copy from the config.go. It is a duplication of the code //for the timebeing to allow reload of the permissioned nodes while the server is running -func parsePermissionedNodes(DataDir string) []*enode.Node { +func ParsePermissionedNodes(DataDir string) []*enode.Node { - log.Debug("parsePermissionedNodes", "DataDir", DataDir, "file", PERMISSIONED_CONFIG) + log.Debug("parsePermissionedNodes", "DataDir", DataDir, "file", params.PERMISSIONED_CONFIG) - path := filepath.Join(DataDir, PERMISSIONED_CONFIG) + path := filepath.Join(DataDir, params.PERMISSIONED_CONFIG) if _, err := os.Stat(path); err != nil { log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present.", "err", err) return nil @@ -75,3 +80,33 @@ func parsePermissionedNodes(DataDir string) []*enode.Node { } return nodes } + +// This function checks if the node is black-listed +func isNodeBlackListed(nodeName, dataDir string) bool { + log.Debug("isNodeBlackListed", "DataDir", dataDir, "file", params.BLACKLIST_CONFIG) + + path := filepath.Join(dataDir, params.BLACKLIST_CONFIG) + if _, err := os.Stat(path); err != nil { + log.Debug("Read Error for disallowed-nodes.json file. disallowed-nodes.json file is not present.", "err", err) + return false + } + // Load the nodes from the config file + blob, err := ioutil.ReadFile(path) + if err != nil { + log.Debug("isNodeBlackListed: Failed to access nodes", "err", err) + return true + } + + nodelist := []string{} + if err := json.Unmarshal(blob, &nodelist); err != nil { + log.Debug("parsePermissionedNodes: Failed to load nodes", "err", err) + return true + } + + for _, v := range nodelist { + if strings.Contains(v, nodeName) { + return true + } + } + return false +} diff --git a/p2p/protocols/protocol_test.go b/p2p/protocols/protocol_test.go index a26222cd8b..41845d747a 100644 --- a/p2p/protocols/protocol_test.go +++ b/p2p/protocols/protocol_test.go @@ -269,8 +269,11 @@ func TestProtocolHook(t *testing.T) { if !testHook.send { t.Fatal("Expected a send message, but it is not") } - if testHook.peer == nil || testHook.peer.ID() != tester.Nodes[0].ID() { - t.Fatal("Expected peer ID to be set correctly, but it is not") + if testHook.peer == nil { + t.Fatal("Expected peer to be set, is nil") + } + if peerId := testHook.peer.ID(); peerId != tester.Nodes[0].ID() && peerId != tester.Nodes[1].ID() { + t.Fatalf("Expected peer ID to be set correctly, but it is not (got %v, exp %v or %v", peerId, tester.Nodes[0].ID(), tester.Nodes[1].ID()) } if testHook.size != 11 { //11 is the length of the encoded message t.Fatalf("Expected size to be %d, but it is %d ", 1, testHook.size) diff --git a/p2p/server.go b/p2p/server.go index 38f73289da..74b251288d 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -190,6 +190,9 @@ type Server struct { loopWG sync.WaitGroup // loop, listenLoop peerFeed event.Feed log log.Logger + + // raft peers info + checkPeerInRaft func(*enode.Node) bool } type peerOpFunc func(map[enode.ID]*Peer) @@ -927,6 +930,14 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro } clog := srv.log.New("id", c.node.ID(), "addr", c.fd.RemoteAddr(), "conn", c.flags) + // If raft is running, check if the dialing node is in the raft cluster + // Node doesn't belong to raft cluster is not allowed to join the p2p network + if srv.checkPeerInRaft != nil && !srv.checkPeerInRaft(c.node) { + node := c.node.ID().String() + log.Trace("incoming connection peer is not in the raft cluster", "enode.id", node) + return newPeerError(errNotInRaftCluster, "id=%s…%s", node[:4], node[len(node)-4:]) + } + //START - QUORUM Permissioning currentNode := srv.NodeInfo().ID cnodeName := srv.NodeInfo().Name @@ -950,7 +961,7 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro } if !isNodePermissioned(node, currentNode, srv.DataDir, direction) { - return nil + return newPeerError(errPermissionDenied, "id=%s…%s %s id=%s…%s", currentNode[:4], currentNode[len(currentNode)-4:], direction, node[:4], node[len(node)-4:]) } } else { clog.Trace("Node Permissioning is Disabled.") @@ -1116,3 +1127,7 @@ func (srv *Server) PeersInfo() []*PeerInfo { } return infos } + +func (srv *Server) SetCheckPeerInRaft(f func(*enode.Node) bool) { + srv.checkPeerInRaft = f +} diff --git a/p2p/server_test.go b/p2p/server_test.go index 22430730d8..34e0962d14 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -19,8 +19,11 @@ package p2p import ( "crypto/ecdsa" "errors" + "io/ioutil" "math/rand" "net" + "os" + "path" "reflect" "testing" "time" @@ -30,6 +33,8 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/assert" ) // func init() { @@ -567,6 +572,74 @@ func TestServerSetupConn(t *testing.T) { } } +func TestServerSetupConn_whenNotInRaftCluster(t *testing.T) { + var ( + clientkey, srvkey = newkey(), newkey() + clientpub = &clientkey.PublicKey + ) + + clientNode := enode.NewV4(clientpub, nil, 0, 0, 0) + srv := &Server{ + Config: Config{ + PrivateKey: srvkey, + NoDiscovery: true, + }, + newTransport: func(fd net.Conn) transport { return newTestTransport(clientpub, fd) }, + log: log.New(), + checkPeerInRaft: func(node *enode.Node) bool { + return false + }, + } + if err := srv.Start(); err != nil { + t.Fatalf("couldn't start server: %v", err) + } + defer srv.Stop() + p1, _ := net.Pipe() + err := srv.SetupConn(p1, inboundConn, clientNode) + + assert.IsType(t, &peerError{}, err) + perr := err.(*peerError) + t.Log(perr.Error()) + assert.Equal(t, errNotInRaftCluster, perr.code) +} + +func TestServerSetupConn_whenNotPermissioned(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + defer func() { _ = os.RemoveAll(tmpDir) }() + if err := ioutil.WriteFile(path.Join(tmpDir, params.PERMISSIONED_CONFIG), []byte("[]"), 0644); err != nil { + t.Fatal(err) + } + var ( + clientkey, srvkey = newkey(), newkey() + clientpub = &clientkey.PublicKey + ) + clientNode := enode.NewV4(clientpub, nil, 0, 0, 0) + srv := &Server{ + Config: Config{ + PrivateKey: srvkey, + NoDiscovery: true, + DataDir: tmpDir, + EnableNodePermission: true, + }, + newTransport: func(fd net.Conn) transport { return newTestTransport(clientpub, fd) }, + log: log.New(), + } + if err := srv.Start(); err != nil { + t.Fatalf("couldn't start server: %v", err) + } + defer srv.Stop() + p1, _ := net.Pipe() + err = srv.SetupConn(p1, inboundConn, clientNode) + + assert.IsType(t, &peerError{}, err) + perr := err.(*peerError) + t.Log(perr.Error()) + assert.Equal(t, errPermissionDenied, perr.code) +} + type setupTransport struct { pubkey *ecdsa.PublicKey encHandshakeErr error diff --git a/params/config.go b/params/config.go index 9322edd8ec..b1f258ec48 100644 --- a/params/config.go +++ b/params/config.go @@ -124,6 +124,7 @@ var ( Istanbul: &IstanbulConfig{ Epoch: 30000, ProposerPolicy: 0, + Ceil2Nby3Block: big.NewInt(0), }, } @@ -132,19 +133,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, 50, big.NewInt(0)} // 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, big.NewInt(0)} - 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, big.NewInt(0)} 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, big.NewInt(0)} ) // TrustedCheckpoint represents a set of post-processed trie roots (CHT and @@ -190,6 +191,11 @@ type ChainConfig struct { IsQuorum bool `json:"isQuorum"` TransactionSizeLimit uint64 `json:"txnSizeLimit"` + MaxCodeSize uint64 `json:"maxCodeSize"` + // Quorum + // + // QIP714Block implements the permissions related changes + QIP714Block *big.Int `json:"qip714Block,omitempty"` } // EthashConfig is the consensus engine configs for proof-of-work based sealing. @@ -213,8 +219,9 @@ func (c *CliqueConfig) String() string { // IstanbulConfig is the consensus engine configs for Istanbul based sealing. type IstanbulConfig struct { - Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint - ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection + Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint + ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection + Ceil2Nby3Block *big.Int `json:"ceil2Nby3Block,omitempty"` // Number of confirmations required to move from one state to next [2F + 1 to Ceil(2N/3)] } // String implements the stringer interface, returning the consensus engine details. @@ -235,7 +242,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v IsQuorum: %v Constantinople: %v Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v IsQuorum: %v Constantinople: %v TransactionSizeLimit: %v MaxCodeSize: %v Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -246,15 +253,22 @@ func (c *ChainConfig) String() string { c.ByzantiumBlock, c.IsQuorum, c.ConstantinopleBlock, + c.TransactionSizeLimit, + c.MaxCodeSize, engine, ) } 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 } @@ -298,6 +312,13 @@ func (c *ChainConfig) IsEWASM(num *big.Int) bool { return isForked(c.EWASMBlock, num) } +// Quorum +// +// IsQIP714 returns whether num represents a block number where permissions is enabled +func (c *ChainConfig) IsQIP714(num *big.Int) bool { + return isForked(c.QIP714Block, num) +} + // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice). // // The returned GasTable's fields shouldn't, under any circumstances, be changed. @@ -369,6 +390,12 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int, isQuor if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) } + if c.Istanbul != nil && newcfg.Istanbul != nil && isForkIncompatible(c.Istanbul.Ceil2Nby3Block, newcfg.Istanbul.Ceil2Nby3Block, head) { + return newCompatError("Ceil 2N/3 fork block", c.Istanbul.Ceil2Nby3Block, newcfg.Istanbul.Ceil2Nby3Block) + } + if isForkIncompatible(c.QIP714Block, newcfg.QIP714Block, head) { + return newCompatError("permissions fork block", c.QIP714Block, newcfg.QIP714Block) + } return nil } diff --git a/params/config_test.go b/params/config_test.go index 61a8bbab74..259205b854 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -70,6 +70,23 @@ func TestCheckCompatible(t *testing.T) { RewindTo: 9, }, }, + { + stored: &ChainConfig{Istanbul: &IstanbulConfig{Ceil2Nby3Block: big.NewInt(10)}}, + new: &ChainConfig{Istanbul: &IstanbulConfig{Ceil2Nby3Block: big.NewInt(20)}}, + head: 4, + wantErr: nil, + }, + { + stored: &ChainConfig{Istanbul: &IstanbulConfig{Ceil2Nby3Block: big.NewInt(10)}}, + new: &ChainConfig{Istanbul: &IstanbulConfig{Ceil2Nby3Block: big.NewInt(20)}}, + head: 30, + wantErr: &ConfigCompatError{ + What: "Ceil 2N/3 fork block", + StoredConfig: big.NewInt(10), + NewConfig: big.NewInt(20), + RewindTo: 9, + }, + }, } for _, test := range tests { diff --git a/params/protocol_params.go b/params/protocol_params.go index a39c8d02c8..b0bff971b7 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -25,7 +25,7 @@ var ( const ( // these are original values from upstream Geth, used in ethash consensus - OriginnalMinGasLimit uint64 = 5000 // The bound divisor of the gas limit, used in update calculations. + OriginalMinGasLimit uint64 = 5000 // The bound divisor of the gas limit, used in update calculations. OriginalGasLimitBoundDivisor uint64 = 1024 // Minimum the gas limit may ever be. // modified values for Quorum diff --git a/params/quorum.go b/params/quorum.go new file mode 100644 index 0000000000..aae309c541 --- /dev/null +++ b/params/quorum.go @@ -0,0 +1,7 @@ +package params + +const ( + PERMISSIONED_CONFIG = "permissioned-nodes.json" + BLACKLIST_CONFIG = "disallowed-nodes.json" + PERMISSION_MODEL_CONFIG = "permission-config.json" +) diff --git a/params/version.go b/params/version.go index 60eaa66f34..df8974dd06 100644 --- a/params/version.go +++ b/params/version.go @@ -27,8 +27,8 @@ const ( VersionMeta = "stable" // Version metadata to append to the version string QuorumVersionMajor = 2 - QuorumVersionMinor = 2 - QuorumVersionPatch = 3 + QuorumVersionMinor = 4 + QuorumVersionPatch = 0 ) // Version holds the textual version string. diff --git a/permission/api.go b/permission/api.go new file mode 100644 index 0000000000..87c6598e9a --- /dev/null +++ b/permission/api.go @@ -0,0 +1,1121 @@ +package permission + +import ( + "errors" + "fmt" + "math/big" + "regexp" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + pbind "github.com/ethereum/go-ethereum/permission/bind" +) + +var isStringAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9_-]*$`).MatchString + +//default gas limit to use if not passed in sendTxArgs +var defaultGasLimit = uint64(4712384) + +//default gas price to use if not passed in sendTxArgs +var defaultGasPrice = big.NewInt(0) + +// PermAction represents actions in permission contract +type PermAction int + +const ( + AddOrg PermAction = iota + ApproveOrg + AddSubOrg + UpdateOrgStatus + ApproveOrgStatus + AddNode + UpdateNodeStatus + AssignAdminRole + ApproveAdminRole + AddNewRole + RemoveRole + AddAccountToOrg + ChangeAccountRole + UpdateAccountStatus + InitiateNodeRecovery + InitiateAccountRecovery + ApproveNodeRecovery + ApproveAccountRecovery +) + +type AccountUpdateAction int + +const ( + SuspendAccount AccountUpdateAction = iota + 1 + ActivateSuspendedAccount + BlacklistAccount + RecoverBlacklistedAccount + ApproveBlacklistedAccountRecovery +) + +type NodeUpdateAction int + +const ( + SuspendNode NodeUpdateAction = iota + 1 + ActivateSuspendedNode + BlacklistNode + RecoverBlacklistedNode + ApproveBlacklistedNodeRecovery +) + +type OrgUpdateAction int + +const ( + SuspendOrg OrgUpdateAction = iota + 1 + ActivateSuspendedOrg +) + +// QuorumControlsAPI provides an API to access Quorum's node permission and org key management related services +type QuorumControlsAPI struct { + permCtrl *PermissionCtrl +} + +// txArgs holds arguments required for execute functions +type txArgs struct { + orgId string + porgId string + url string + roleId string + isVoter bool + isAdmin bool + acctId common.Address + accessType uint8 + action uint8 + voter common.Address + morgId string + tmKey string + txa ethapi.SendTxArgs +} + +type PendingOpInfo struct { + PendingKey string `json:"pendingKey"` + PendingOp string `json:"pendingOp"` +} + +type ExecStatus struct { + Status bool `json:"status"` + Msg string `json:"msg"` +} + +func (e ExecStatus) OpStatus() (string, error) { + if e.Status { + return e.Msg, nil + } + return "", fmt.Errorf("%s", e.Msg) +} + +var ( + ErrNotNetworkAdmin = ExecStatus{false, "Operation can be performed by network admin only. Account not a network admin."} + ErrNotOrgAdmin = ExecStatus{false, "Operation can be performed by org admin only. Account not a org admin."} + ErrNodePresent = ExecStatus{false, "EnodeId already part of network."} + ErrInvalidNode = ExecStatus{false, "Invalid enode id"} + ErrInvalidAccount = ExecStatus{false, "Invalid account id"} + ErrOrgExists = ExecStatus{false, "Org already exists"} + ErrPendingApprovals = ExecStatus{false, "Pending approvals for the organization. Approve first"} + ErrNothingToApprove = ExecStatus{false, "Nothing to approve"} + ErrOpNotAllowed = ExecStatus{false, "Operation not allowed"} + ErrNodeOrgMismatch = ExecStatus{false, "Enode id passed does not belong to the organization."} + ErrBlacklistedNode = ExecStatus{false, "Blacklisted node. Operation not allowed"} + ErrBlacklistedAccount = ExecStatus{false, "Blacklisted account. Operation not allowed"} + ErrAccountOrgAdmin = ExecStatus{false, "Account already org admin for the org"} + ErrOrgAdminExists = ExecStatus{false, "Org admin exists for the org"} + ErrAccountInUse = ExecStatus{false, "Account already in use in another organization"} + ErrRoleExists = ExecStatus{false, "Role exists for the org"} + ErrRoleActive = ExecStatus{false, "Accounts linked to the role. Cannot be removed"} + ErrAdminRoles = ExecStatus{false, "Admin role cannot be removed"} + ErrInvalidOrgName = ExecStatus{false, "Org id cannot contain special characters"} + ErrInvalidParentOrg = ExecStatus{false, "Invalid parent org id"} + ErrAccountNotThere = ExecStatus{false, "Account does not exists"} + ErrOrgNotOwner = ExecStatus{false, "Account does not belong to this org"} + ErrMaxDepth = ExecStatus{false, "Max depth for sub orgs reached"} + ErrMaxBreadth = ExecStatus{false, "Max breadth for sub orgs reached"} + ErrNodeDoesNotExists = ExecStatus{false, "Node does not exists"} + ErrOrgDoesNotExists = ExecStatus{false, "Org does not exists"} + ErrInactiveRole = ExecStatus{false, "Role is already inactive"} + ErrInvalidRole = ExecStatus{false, "Invalid role"} + ErrInvalidInput = ExecStatus{false, "Invalid input"} + ErrNotMasterOrg = ExecStatus{false, "Org is not a master org"} + + ExecSuccess = ExecStatus{true, "Action completed successfully"} +) + +// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services +func NewQuorumControlsAPI(p *PermissionCtrl) *QuorumControlsAPI { + return &QuorumControlsAPI{p} +} + +func (q *QuorumControlsAPI) OrgList() []types.OrgInfo { + return types.OrgInfoMap.GetOrgList() +} + +func (q *QuorumControlsAPI) NodeList() []types.NodeInfo { + return types.NodeInfoMap.GetNodeList() +} + +func (q *QuorumControlsAPI) RoleList() []types.RoleInfo { + return types.RoleInfoMap.GetRoleList() +} + +func (q *QuorumControlsAPI) AcctList() []types.AccountInfo { + return types.AcctInfoMap.GetAcctList() +} + +func (q *QuorumControlsAPI) GetOrgDetails(orgId string) (types.OrgDetailInfo, error) { + if o := types.OrgInfoMap.GetOrg(orgId); o == nil { + return types.OrgDetailInfo{}, errors.New("org does not exist") + } + var acctList []types.AccountInfo + var roleList []types.RoleInfo + var nodeList []types.NodeInfo + for _, a := range q.AcctList() { + if a.OrgId == orgId { + acctList = append(acctList, a) + } + } + for _, a := range q.RoleList() { + if a.OrgId == orgId { + roleList = append(roleList, a) + } + } + for _, a := range q.NodeList() { + if a.OrgId == orgId { + nodeList = append(nodeList, a) + } + } + return types.OrgDetailInfo{NodeList: nodeList, RoleList: roleList, AcctList: acctList, SubOrgList: types.OrgInfoMap.GetOrg(orgId).SubOrgList}, nil +} + +func (q *QuorumControlsAPI) initOp(txa ethapi.SendTxArgs) (*pbind.PermInterfaceSession, ExecStatus) { + var err error + var w accounts.Wallet + + w, err = q.validateAccount(txa.From) + if err != nil { + return nil, ErrInvalidAccount + } + pinterf := q.newPermInterfaceSession(w, txa) + + return pinterf, ExecSuccess +} + +func reportExecError(action PermAction, err error) (string, error) { + log.Error("Failed to execute permission action", "action", action, "err", err) + msg := fmt.Sprintf("failed to execute permissions action: %v", err) + return ExecStatus{false, msg}.OpStatus() +} + +func (q *QuorumControlsAPI) AddOrg(orgId string, url string, acct common.Address, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: url, acctId: acct, txa: txa} + + if execStatus := q.valAddOrg(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.AddOrg(args.orgId, args.url, args.acctId) + if err != nil { + return reportExecError(AddOrg, err) + } + log.Debug("executed permission action", "action", AddOrg, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) AddSubOrg(porgId, orgId string, url string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{porgId: porgId, orgId: orgId, url: url, txa: txa} + + if execStatus := q.valAddSubOrg(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.AddSubOrg(args.porgId, args.orgId, args.url) + if err != nil { + return reportExecError(AddSubOrg, err) + } + log.Debug("executed permission action", "action", AddSubOrg, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) ApproveOrg(orgId string, url string, acct common.Address, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: url, acctId: acct, txa: txa} + if execStatus := q.valApproveOrg(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.ApproveOrg(args.orgId, args.url, args.acctId) + if err != nil { + return reportExecError(ApproveOrg, err) + } + log.Debug("executed permission action", "action", ApproveOrg, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) UpdateOrgStatus(orgId string, status uint8, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, action: status, txa: txa} + if execStatus := q.valUpdateOrgStatus(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // and in suspended state for suspension revoke + tx, err := pinterf.UpdateOrgStatus(args.orgId, big.NewInt(int64(args.action))) + if err != nil { + return reportExecError(UpdateOrgStatus, err) + } + log.Debug("executed permission action", "action", UpdateOrgStatus, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) AddNode(orgId string, url string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: url, txa: txa} + if execStatus := q.valAddNode(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // check if node is already there + tx, err := pinterf.AddNode(args.orgId, args.url) + if err != nil { + return reportExecError(AddNode, err) + } + log.Debug("executed permission action", "action", AddNode, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) UpdateNodeStatus(orgId string, url string, action uint8, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: url, action: action, txa: txa} + if execStatus := q.valUpdateNodeStatus(args, UpdateNodeStatus, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // check node status for operation + tx, err := pinterf.UpdateNodeStatus(args.orgId, args.url, big.NewInt(int64(args.action))) + if err != nil { + return reportExecError(UpdateNodeStatus, err) + } + log.Debug("executed permission action", "action", UpdateNodeStatus, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) ApproveOrgStatus(orgId string, status uint8, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, action: status, txa: txa} + if execStatus := q.valApproveOrgStatus(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // validate that status change is pending approval + tx, err := pinterf.ApproveOrgStatus(args.orgId, big.NewInt(int64(args.action))) + if err != nil { + return reportExecError(ApproveOrgStatus, err) + } + log.Debug("executed permission action", "action", ApproveOrgStatus, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) AssignAdminRole(orgId string, acct common.Address, roleId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, acctId: acct, roleId: roleId, txa: txa} + if execStatus := q.valAssignAdminRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // check if account is already in use in another org + tx, err := pinterf.AssignAdminRole(args.orgId, args.acctId, args.roleId) + if err != nil { + return reportExecError(AssignAdminRole, err) + } + log.Debug("executed permission action", "action", AssignAdminRole, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) ApproveAdminRole(orgId string, acct common.Address, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, acctId: acct, txa: txa} + if execStatus := q.valApproveAdminRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // check if anything is pending approval + tx, err := pinterf.ApproveAdminRole(args.orgId, args.acctId) + if err != nil { + return reportExecError(ApproveAdminRole, err) + } + log.Debug("executed permission action", "action", ApproveAdminRole, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) AddNewRole(orgId string, roleId string, access uint8, isVoter bool, isAdmin bool, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, roleId: roleId, accessType: access, isVoter: isVoter, isAdmin: isAdmin, txa: txa} + if execStatus := q.valAddNewRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + // check if role is already there in the org + tx, err := pinterf.AddNewRole(args.roleId, args.orgId, big.NewInt(int64(args.accessType)), args.isVoter, args.isAdmin) + if err != nil { + return reportExecError(AddNewRole, err) + } + log.Debug("executed permission action", "action", AddNewRole, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) RemoveRole(orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, roleId: roleId, txa: txa} + + if execStatus := q.valRemoveRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.RemoveRole(args.roleId, args.orgId) + if err != nil { + return reportExecError(RemoveRole, err) + } + log.Debug("executed permission action", "action", RemoveRole, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) AddAccountToOrg(acct common.Address, orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, roleId: roleId, acctId: acct, txa: txa} + + if execStatus := q.valAssignRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.AssignAccountRole(args.acctId, args.orgId, args.roleId) + if err != nil { + return reportExecError(AddAccountToOrg, err) + } + log.Debug("executed permission action", "action", AddAccountToOrg, "tx", tx) + return ExecSuccess.OpStatus() +} +func (q *QuorumControlsAPI) ChangeAccountRole(acct common.Address, orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, roleId: roleId, acctId: acct, txa: txa} + + if execStatus := q.valAssignRole(args, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.AssignAccountRole(args.acctId, args.orgId, args.roleId) + if err != nil { + return reportExecError(ChangeAccountRole, err) + } + log.Debug("executed permission action", "action", ChangeAccountRole, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) UpdateAccountStatus(orgId string, acct common.Address, status uint8, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, acctId: acct, action: status, txa: txa} + + if execStatus := q.valUpdateAccountStatus(args, UpdateAccountStatus, pinterf); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.UpdateAccountStatus(args.orgId, args.acctId, big.NewInt(int64(args.action))) + if err != nil { + return reportExecError(UpdateAccountStatus, err) + } + log.Debug("executed permission action", "action", UpdateAccountStatus, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) RecoverBlackListedNode(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: enodeId, txa: txa} + + if execStatus := q.valRecoverNode(args, pinterf, InitiateNodeRecovery); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.StartBlacklistedNodeRecovery(args.orgId, args.url) + if err != nil { + return reportExecError(InitiateNodeRecovery, err) + } + log.Debug("executed permission action", "action", InitiateNodeRecovery, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) ApproveBlackListedNodeRecovery(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, url: enodeId, txa: txa} + + if execStatus := q.valRecoverNode(args, pinterf, ApproveNodeRecovery); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.ApproveBlacklistedNodeRecovery(args.orgId, args.url) + if err != nil { + return reportExecError(ApproveNodeRecovery, err) + } + log.Debug("executed permission action", "action", ApproveNodeRecovery, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) RecoverBlackListedAccount(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, acctId: acctId, txa: txa} + + if execStatus := q.valRecoverAccount(args, pinterf, InitiateAccountRecovery); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.StartBlacklistedAccountRecovery(args.orgId, args.acctId) + if err != nil { + return reportExecError(InitiateAccountRecovery, err) + } + log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx) + return ExecSuccess.OpStatus() +} + +func (q *QuorumControlsAPI) ApproveBlackListedAccountRecovery(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) { + pinterf, execStatus := q.initOp(txa) + if execStatus != ExecSuccess { + return execStatus.OpStatus() + } + args := txArgs{orgId: orgId, acctId: acctId, txa: txa} + + if execStatus := q.valRecoverAccount(args, pinterf, ApproveAccountRecovery); execStatus != ExecSuccess { + return execStatus.OpStatus() + } + tx, err := pinterf.ApproveBlacklistedAccountRecovery(args.orgId, args.acctId) + if err != nil { + return reportExecError(ApproveAccountRecovery, err) + } + log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx) + return ExecSuccess.OpStatus() +} + +// check if the account is network admin +func (q *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool { + ac := types.AcctInfoMap.GetAccount(account) + return ac != nil && ac.RoleId == q.permCtrl.permConfig.NwAdminRole +} + +func (q *QuorumControlsAPI) isOrgAdmin(account common.Address, orgId string) (ExecStatus, error) { + org := types.OrgInfoMap.GetOrg(orgId) + if org == nil { + return ErrOrgDoesNotExists, errors.New("invalid org") + } + ac := types.AcctInfoMap.GetAccount(account) + if ac == nil { + return ErrNotOrgAdmin, errors.New("not org admin") + } + // check if the account is network admin + if !(ac.IsOrgAdmin && (ac.OrgId == orgId || ac.OrgId == org.UltimateParent)) { + return ErrNotOrgAdmin, errors.New("not org admin") + } + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) validateOrg(orgId, pOrgId string) (ExecStatus, error) { + // validate Parent org id + if pOrgId != "" { + if types.OrgInfoMap.GetOrg(pOrgId) == nil { + return ErrInvalidParentOrg, errors.New("invalid parent org") + } + locOrgId := pOrgId + "." + orgId + if types.OrgInfoMap.GetOrg(locOrgId) != nil { + return ErrOrgExists, errors.New("org exists") + } + } else if types.OrgInfoMap.GetOrg(orgId) != nil { + return ErrOrgExists, errors.New("org exists") + } + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) validatePendingOp(authOrg, orgId, url string, account common.Address, pendingOp int64, pinterf *pbind.PermInterfaceSession) bool { + pOrg, pUrl, pAcct, op, err := pinterf.GetPendingOp(authOrg) + return err == nil && (op.Int64() == pendingOp && pOrg == orgId && pUrl == url && pAcct == account) +} + +func (q *QuorumControlsAPI) checkPendingOp(orgId string, pinterf *pbind.PermInterfaceSession) bool { + _, _, _, op, err := pinterf.GetPendingOp(orgId) + return err == nil && op.Int64() != 0 +} + +func (q *QuorumControlsAPI) checkOrgStatus(orgId string, op uint8) (ExecStatus, error) { + org := types.OrgInfoMap.GetOrg(orgId) + + if org == nil { + return ErrOrgDoesNotExists, errors.New("org does not exist") + } + // check if its a master org. operation is allowed only if its a master org + if org.Level.Cmp(big.NewInt(1)) != 0 { + return ErrNotMasterOrg, errors.New("org not a master org") + } + + if !((op == 1 && org.Status == types.OrgApproved) || (op == 2 && org.Status == types.OrgSuspended)) { + return ErrOpNotAllowed, errors.New("operation not allowed for current status") + } + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) valNodeStatusChange(orgId, url string, op NodeUpdateAction, permAction PermAction) (ExecStatus, error) { + // validates if the enode is linked the passed organization + // validate node id and + if len(url) == 0 { + return ErrInvalidNode, errors.New("invalid node id") + } + if execStatus, err := q.valNodeDetails(url); err != nil && execStatus != ErrNodePresent { + return execStatus, errors.New("node not found") + } + + node := types.NodeInfoMap.GetNodeByUrl(url) + if node != nil { + if node.OrgId != orgId { + return ErrNodeOrgMismatch, errors.New("node does not belong to the organization passed") + } + + if node.Status == types.NodeBlackListed && op != RecoverBlacklistedNode { + return ErrBlacklistedNode, errors.New("blacklisted node. operation not allowed") + } + + // validate the op and node status and check if the op can be performed + if (permAction == UpdateNodeStatus && (op != SuspendNode && op != ActivateSuspendedNode && op != BlacklistNode)) || + (permAction == InitiateNodeRecovery && op != RecoverBlacklistedNode) || + (permAction == ApproveNodeRecovery && op != ApproveBlacklistedNodeRecovery) { + return ErrOpNotAllowed, errors.New("invalid node status change operation") + } + + if (op == SuspendNode && node.Status != types.NodeApproved) || + (op == ActivateSuspendedNode && node.Status != types.NodeDeactivated) || + (op == BlacklistNode && node.Status == types.NodeRecoveryInitiated) || + (op == RecoverBlacklistedNode && node.Status != types.NodeBlackListed) || + (op == ApproveBlacklistedNodeRecovery && node.Status != types.NodeRecoveryInitiated) { + return ErrOpNotAllowed, errors.New("node status change cannot be performed") + } + } else { + return ErrNodeDoesNotExists, errors.New("node does not exist") + } + + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) validateRole(orgId, roleId string) bool { + var r *types.RoleInfo + r = types.RoleInfoMap.GetRole(orgId, roleId) + if r == nil { + r = types.RoleInfoMap.GetRole(types.OrgInfoMap.GetOrg(orgId).UltimateParent, roleId) + } + + return r != nil && r.Active +} + +func (q *QuorumControlsAPI) valAccountStatusChange(orgId string, account common.Address, permAction PermAction, op AccountUpdateAction) (ExecStatus, error) { + // validates if the enode is linked the passed organization + ac := types.AcctInfoMap.GetAccount(account) + + if ac == nil { + return ErrAccountNotThere, errors.New("account not there") + } + + if ac.IsOrgAdmin && (ac.RoleId == q.permCtrl.permConfig.NwAdminRole || ac.RoleId == q.permCtrl.permConfig.OrgAdminRole) && (op == 1 || op == 3) { + return ErrOpNotAllowed, errors.New("operation not allowed on org admin account") + } + + if ac.OrgId != orgId { + return ErrOrgNotOwner, errors.New("account does not belong to the organization passed") + } + if (permAction == UpdateAccountStatus && (op != SuspendAccount && op != ActivateSuspendedAccount && op != BlacklistAccount)) || + (permAction == InitiateAccountRecovery && op != RecoverBlacklistedAccount) || + (permAction == ApproveAccountRecovery && op != ApproveBlacklistedAccountRecovery) { + return ErrOpNotAllowed, errors.New("invalid account status change operation") + } + + if ac.Status == types.AcctBlacklisted && op != RecoverBlacklistedAccount { + return ErrBlacklistedAccount, errors.New("blacklisted account. operation not allowed") + } + + if (op == SuspendAccount && ac.Status != types.AcctActive) || + (op == ActivateSuspendedAccount && ac.Status != types.AcctSuspended) || + (op == BlacklistAccount && ac.Status == types.AcctRecoveryInitiated) || + (op == RecoverBlacklistedAccount && ac.Status != types.AcctBlacklisted) || + (op == ApproveBlacklistedAccountRecovery && ac.Status != types.AcctRecoveryInitiated) { + return ErrOpNotAllowed, errors.New("account status change cannot be performed") + } + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account common.Address) (ExecStatus, error) { + ac := types.AcctInfoMap.GetAccount(account) + + if ac != nil { + if ac.OrgId != orgId { + return ErrAccountInUse, errors.New("account part of another org") + } + if roleId != "" && roleId == q.permCtrl.permConfig.OrgAdminRole && ac.IsOrgAdmin { + return ErrAccountOrgAdmin, errors.New("account already org admin for the org") + } + } + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) valSubOrgBreadthDepth(porgId string) (ExecStatus, error) { + org := types.OrgInfoMap.GetOrg(porgId) + + if q.permCtrl.permConfig.SubOrgDepth.Cmp(org.Level) == 0 { + return ErrMaxDepth, errors.New("max depth for sub orgs reached") + } + + if q.permCtrl.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 { + return ErrMaxBreadth, errors.New("max breadth for sub orgs reached") + } + + return ExecSuccess, nil +} + +func (q *QuorumControlsAPI) checkNodeExists(url, enodeId string) bool { + node := types.NodeInfoMap.GetNodeByUrl(url) + if node != nil { + return true + } + // check if the same nodeid is in use with different port numbers + nodeList := types.NodeInfoMap.GetNodeList() + for _, n := range nodeList { + if enodeDet, er := enode.ParseV4(n.Url); er == nil { + if enodeDet.EnodeID() == enodeId { + return true + } + } + } + return false +} + +func (q *QuorumControlsAPI) valNodeDetails(url string) (ExecStatus, error) { + // validate node id and + if len(url) != 0 { + enodeDet, err := enode.ParseV4(url) + if err != nil { + return ErrInvalidNode, errors.New("invalid node id") + } + // check if node already there + if q.checkNodeExists(url, enodeDet.EnodeID()) { + return ErrNodePresent, errors.New("duplicate node") + } + } + return ExecSuccess, nil +} + +// all validations for add org operation +func (q *QuorumControlsAPI) valAddOrg(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if the org id contains "." + if args.orgId == "" || args.url == "" || args.acctId == (common.Address{0}) { + return ErrInvalidInput + } + if !isStringAlphaNumeric(args.orgId) { + return ErrInvalidOrgName + } + + // check if caller is network admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + + // check if any previous op is pending approval for network admin + if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) { + return ErrPendingApprovals + } + // check if org already exists + if execStatus, er := q.validateOrg(args.orgId, ""); er != nil { + return execStatus + } + + // validate node id and + if execStatus, er := q.valNodeDetails(args.url); er != nil { + return execStatus + } + + // check if account is already part of another org + if execStatus, er := q.checkOrgAdminExists(args.orgId, "", args.acctId); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valApproveOrg(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check caller is network admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + // check if anything pending approval + if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, args.url, args.acctId, 1, pinterf) { + return ErrNothingToApprove + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valAddSubOrg(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if the org id contains "." + if args.orgId == "" { + return ErrInvalidInput + } + if !isStringAlphaNumeric(args.orgId) { + return ErrInvalidOrgName + } + + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.porgId); er != nil { + return execStatus + } + + // check if org already exists + if execStatus, er := q.validateOrg(args.orgId, args.porgId); er != nil { + return execStatus + } + + if execStatus, er := q.valSubOrgBreadthDepth(args.porgId); er != nil { + return execStatus + } + + if execStatus, er := q.valNodeDetails(args.url); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valUpdateOrgStatus(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if called is network admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + if OrgUpdateAction(args.action) != SuspendOrg && + OrgUpdateAction(args.action) != ActivateSuspendedOrg { + return ErrOpNotAllowed + } + + //check if passed org id is network admin org. update should not be allowed + if args.orgId == q.permCtrl.permConfig.NwAdminOrg { + return ErrOpNotAllowed + } + // check if status update can be performed. Org should be approved for suspension + if execStatus, er := q.checkOrgStatus(args.orgId, args.action); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valApproveOrgStatus(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if called is network admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + // check if anything is pending approval + var pendingOp int64 + if args.action == 1 { + pendingOp = 2 + } else if args.action == 2 { + pendingOp = 3 + } else { + return ErrOpNotAllowed + } + if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, "", common.Address{}, pendingOp, pinterf) { + return ErrNothingToApprove + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valAddNode(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + if args.url == "" { + return ErrInvalidInput + } + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + + if execStatus, er := q.valNodeDetails(args.url); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valUpdateNodeStatus(args txArgs, permAction PermAction, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if org admin + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + + // validation status change is with in allowed set + if execStatus, er := q.valNodeStatusChange(args.orgId, args.url, NodeUpdateAction(args.action), permAction); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valAssignAdminRole(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + if args.acctId == (common.Address{0}) { + return ErrInvalidInput + } + // check if caller is network admin + if args.roleId != q.permCtrl.permConfig.OrgAdminRole && args.roleId != q.permCtrl.permConfig.NwAdminRole { + return ErrOpNotAllowed + } + + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + + if _, err := q.validateOrg(args.orgId, ""); err == nil { + return ErrOrgDoesNotExists + } + + // check if account is already part of another org + if execStatus, er := q.checkOrgAdminExists(args.orgId, args.roleId, args.acctId); er != nil && execStatus != ErrOrgAdminExists { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valApproveAdminRole(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if caller is network admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + // check if the org exists + + // check if account is valid + ac := types.AcctInfoMap.GetAccount(args.acctId) + if ac == nil { + return ErrInvalidAccount + } + // validate pending op + if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, ac.OrgId, "", args.acctId, 4, pinterf) { + return ErrNothingToApprove + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valAddNewRole(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + if args.roleId == "" { + return ErrInvalidInput + } + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + // validate if role is already present + if types.RoleInfoMap.GetRole(args.orgId, args.roleId) != nil { + return ErrRoleExists + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valRemoveRole(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + + // admin roles cannot be removed + if args.roleId == q.permCtrl.permConfig.OrgAdminRole || args.roleId == q.permCtrl.permConfig.NwAdminRole { + return ErrAdminRoles + } + + // check if role is alraedy inactive + r := types.RoleInfoMap.GetRole(args.orgId, args.roleId) + if r == nil { + return ErrInvalidRole + } else if !r.Active { + return ErrInactiveRole + } + + // check if the role has active accounts. if yes operations should not be allowed + if len(types.AcctInfoMap.GetAcctListRole(args.orgId, args.roleId)) != 0 { + return ErrRoleActive + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valAssignRole(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus { + if args.acctId == (common.Address{0}) { + return ErrInvalidInput + } + if args.roleId == q.permCtrl.permConfig.OrgAdminRole || args.roleId == q.permCtrl.permConfig.NwAdminRole { + return ErrInvalidRole + } + // check if caller is network admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + + // check if the role is valid + if !q.validateRole(args.orgId, args.roleId) { + return ErrInvalidRole + } + + // check if the account is part of another org + if ac := types.AcctInfoMap.GetAccount(args.acctId); ac != nil { + if ac.OrgId != args.orgId { + return ErrAccountInUse + } + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valUpdateAccountStatus(args txArgs, permAction PermAction, pinterf *pbind.PermInterfaceSession) ExecStatus { + // check if the caller is org admin + if execStatus, er := q.isOrgAdmin(args.txa.From, args.orgId); er != nil { + return execStatus + } + // validation status change is with in allowed set + if execStatus, er := q.valAccountStatusChange(args.orgId, args.acctId, permAction, AccountUpdateAction(args.action)); er != nil { + return execStatus + } + return ExecSuccess +} + +func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInterfaceSession, action PermAction) ExecStatus { + // check if the caller is org admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + // validate inputs - org id is valid, node is valid and in blacklisted state + if execStatus, _ := q.validateOrg(args.orgId, ""); execStatus != ErrOrgExists { + return ErrInvalidOrgName + } + + if action == InitiateNodeRecovery { + if execStatus, _ := q.valNodeStatusChange(args.orgId, args.url, 4, InitiateAccountRecovery); execStatus != ExecSuccess { + return execStatus + } + // check no pending approval items + if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) { + return ErrPendingApprovals + } + } else { + // validate inputs - org id is valid, node is valid pending recovery state + if execStatus, _ := q.valNodeStatusChange(args.orgId, args.url, 5, ApproveNodeRecovery); execStatus != ExecSuccess { + return execStatus + } + + // check that there is a pending approval item for node recovery + if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, args.url, common.Address{}, 5, pinterf) { + return ErrNothingToApprove + } + } + + // if it is approval ensure that + + return ExecSuccess +} + +func (q *QuorumControlsAPI) valRecoverAccount(args txArgs, pinterf *pbind.PermInterfaceSession, action PermAction) ExecStatus { + // check if the caller is org admin + if !q.isNetworkAdmin(args.txa.From) { + return ErrNotNetworkAdmin + } + + var opAction AccountUpdateAction + if action == InitiateAccountRecovery { + opAction = RecoverBlacklistedAccount + } else { + opAction = ApproveBlacklistedAccountRecovery + } + + if execStatus, err := q.valAccountStatusChange(args.orgId, args.acctId, action, opAction); err != nil { + return execStatus + } + + if action == InitiateAccountRecovery && q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) { + return ErrPendingApprovals + } + + if action == ApproveAccountRecovery && !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, "", args.acctId, 6, pinterf) { + return ErrNothingToApprove + } + return ExecSuccess +} + +// validateAccount validates the account and returns the wallet associated with that for signing the transaction +func (q *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) { + acct := accounts.Account{Address: from} + w, err := q.permCtrl.eth.AccountManager().Find(acct) + if err != nil { + return nil, err + } + return w, nil +} + +func (q *QuorumControlsAPI) newPermInterfaceSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermInterfaceSession { + frmAcct, transactOpts, gasLimit, gasPrice := q.getTxParams(txa, w) + ps := &pbind.PermInterfaceSession{ + Contract: q.permCtrl.permInterf, + CallOpts: bind.CallOpts{ + Pending: true, + }, + TransactOpts: bind.TransactOpts{ + From: frmAcct.Address, + GasLimit: gasLimit, + GasPrice: gasPrice, + Signer: transactOpts.Signer, + }, + } + return ps +} + +// getTxParams extracts the transaction related parameters +func (q *QuorumControlsAPI) getTxParams(txa ethapi.SendTxArgs, w accounts.Wallet) (accounts.Account, *bind.TransactOpts, uint64, *big.Int) { + fromAcct := accounts.Account{Address: txa.From} + transactOpts := bind.NewWalletTransactor(w, fromAcct) + gasLimit := defaultGasLimit + gasPrice := defaultGasPrice + if txa.GasPrice != nil { + gasPrice = txa.GasPrice.ToInt() + } + if txa.Gas != nil { + gasLimit = uint64(*txa.Gas) + } + return fromAcct, transactOpts, gasLimit, gasPrice +} diff --git a/permission/bind/accounts.go b/permission/bind/accounts.go new file mode 100644 index 0000000000..3de510ab60 --- /dev/null +++ b/permission/bind/accounts.go @@ -0,0 +1,892 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// AcctManagerABI is the input ABI used to generate the binding from. +const AcctManagerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_adminRole\",\"type\":\"bool\"}],\"name\":\"assignAccountRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"removeExistingAdmin\",\"outputs\":[{\"name\":\"voterUpdate\",\"type\":\"bool\"},{\"name\":\"account\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountDetails\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfAccounts\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"validateAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountRole\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateAccountStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"orgAdminExists\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_aIndex\",\"type\":\"uint256\"}],\"name\":\"getAccountDetailsFromIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"addNewAdmin\",\"outputs\":[{\"name\":\"voterUpdate\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nwAdminRole\",\"type\":\"string\"},{\"name\":\"_oAdminRole\",\"type\":\"string\"}],\"name\":\"setDefaults\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_status\",\"type\":\"uint256\"}],\"name\":\"assignAdminRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_ultParent\",\"type\":\"string\"}],\"name\":\"checkOrgAdmin\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_account\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_roleId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgAdmin\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"_status\",\"type\":\"uint256\"}],\"name\":\"AccountAccessModified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_account\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_roleId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgAdmin\",\"type\":\"bool\"}],\"name\":\"AccountAccessRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_account\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_status\",\"type\":\"uint256\"}],\"name\":\"AccountStatusChanged\",\"type\":\"event\"}]" + +// AcctManagerBin is the compiled bytecode used for deploying new contracts. +const AcctManagerBin = `608060405234801561001057600080fd5b50604051602080620048c18339810180604052602081101561003157600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061482e80620000936000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806384b7a84a116100a9578063c214e5e511610083578063c214e5e514610877578063cef7f6af14610928578063e3483a9d146109f6578063e8b42bf414610aee576100ec565b806384b7a84a146105a9578063950145cf1461064c578063b20185681461071f576100ec565b8063143a5604146100f15780631d09dc93146101eb5780632aceb534146102af578063309e36ef1461041d5780636b568d761461043b57806381d66b23146104ec575b600080fd5b6101e96004803603608081101561010757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561014457600080fd5b82018360208201111561015657600080fd5b8035906020019184600183028401116401000000008311171561017857600080fd5b90919293919293908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390803515159060200190929190505050610c78565b005b6102626004803603602081101561020157600080fd5b810190808035906020019064010000000081111561021e57600080fd5b82018360208201111561023057600080fd5b8035906020019184600183028401116401000000008311171561025257600080fd5b9091929391929390505050611157565b60405180831515151581526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6102f1600480360360208110156102c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611823565b604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185815260200184151515158152602001838103835287818151815260200191508051906020019080838360005b8381101561037757808201518184015260208101905061035c565b50505050905090810190601f1680156103a45780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b838110156103dd5780820151818401526020810190506103c2565b50505050905090810190601f16801561040a5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b610425611afe565b6040518082815260200191505060405180910390f35b6104d26004803603604081101561045157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561048e57600080fd5b8201836020820111156104a057600080fd5b803590602001918460018302840111640100000000831117156104c257600080fd5b9091929391929390505050611b0b565b604051808215151515815260200191505060405180910390f35b61052e6004803603602081101561050257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c91565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561056e578082015181840152602081019050610553565b50505050905090810190601f16801561059b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61064a600480360360608110156105bf57600080fd5b81019080803590602001906401000000008111156105dc57600080fd5b8201836020820111156105ee57600080fd5b8035906020019184600183028401116401000000008311171561061057600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e4f565b005b6107056004803603602081101561066257600080fd5b810190808035906020019064010000000081111561067f57600080fd5b82018360208201111561069157600080fd5b803590602001918460018302840111640100000000831117156106b357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612781565b604051808215151515815260200191505060405180910390f35b61074b6004803603602081101561073557600080fd5b8101908080359060200190929190505050612957565b604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185815260200184151515158152602001838103835287818151815260200191508051906020019080838360005b838110156107d15780820151818401526020810190506107b6565b50505050905090810190601f1680156107fe5780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b8381101561083757808201518184015260208101905061081c565b50505050905090810190601f1680156108645780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b61090e6004803603604081101561088d57600080fd5b81019080803590602001906401000000008111156108aa57600080fd5b8201836020820111156108bc57600080fd5b803590602001918460018302840111640100000000831117156108de57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b7a565b604051808215151515815260200191505060405180910390f35b6109f46004803603604081101561093e57600080fd5b810190808035906020019064010000000081111561095b57600080fd5b82018360208201111561096d57600080fd5b8035906020019184600183028401116401000000008311171561098f57600080fd5b9091929391929390803590602001906401000000008111156109b057600080fd5b8201836020820111156109c257600080fd5b803590602001918460018302840111640100000000831117156109e457600080fd5b90919293919293905050506132e3565b005b610aec60048036036080811015610a0c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a4957600080fd5b820183602082011115610a5b57600080fd5b80359060200191846001830284011164010000000083111715610a7d57600080fd5b909192939192939080359060200190640100000000811115610a9e57600080fd5b820183602082011115610ab057600080fd5b80359060200191846001830284011164010000000083111715610ad257600080fd5b90919293919293908035906020019092919050505061346d565b005b610c5e60048036036060811015610b0457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610b4157600080fd5b820183602082011115610b5357600080fd5b80359060200191846001830284011164010000000083111715610b7557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610bd857600080fd5b820183602082011115610bea57600080fd5b80359060200191846001830284011164010000000083111715610c0c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506138c5565b604051808215151515815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610cfb57600080fd5b505afa158015610d0f573d6000803e3d6000fd5b505050506040513d6020811015610d2557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60046040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610e665780601f10610e3b57610100808354040283529160200191610e66565b820191906000526020600020905b815481529060010190602001808311610e4957829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014158015611062575060056040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610f6c5780601f10610f4157610100808354040283529160200191610f6c565b820191906000526020600020905b815481529060010190602001808311610f4f57829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040526040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015611017578082015181840152602081019050610ffc565b50505050905090810190601f1680156110445780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012014155b15156110b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604081526020018061475e6040913960400191505060405180910390fd5b61114f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600285613ebc565b505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156111dd57600080fd5b505afa1580156111f1573d6000803e3d6000fd5b505050506040513d602081101561120757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b61130784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612781565b1561181157600061139c60066000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166143d6565b905060066001828154811015156113af57fe5b90600052602060002090600502016003018190555060006001828154811015156113d557fe5b906000526020600020906005020160040160006101000a81548160ff0219169083151502179055507f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc77660018281548110151561142d57fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018381548110151561146e57fe5b906000526020600020906005020160010160018481548110151561148e57fe5b90600052602060002090600502016002016001858154811015156114ae57fe5b906000526020600020906005020160040160009054906101000a900460ff166001868154811015156114dc57fe5b906000526020600020906005020160030154604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001851515151581526020018481526020018381038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156115bd5780601f10611592576101008083540402835291602001916115bd565b820191906000526020600020905b8154815290600101906020018083116115a057829003601f168201915b50508381038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156116405780601f1061161557610100808354040283529160200191611640565b820191906000526020600020905b81548152906001019060200180831161162357829003601f168201915b505097505050505050505060405180910390a1600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156116e15780601f106116b6576101008083540402835291602001916116e1565b820191906000526020600020905b8154815290600101906020018083116116c457829003601f168201915b5050925050506040516020818303038152906040528051906020012060018281548110151561170c57fe5b906000526020600020906005020160020160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156117a95780601f1061177e576101008083540402835291602001916117a9565b820191906000526020600020905b81548152906001019060200180831161178c57829003601f168201915b50509250505060405160208183030381529060405280519060200120146001828154811015156117d557fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16925092505061181c565b600080809050915091505b9250929050565b60006060806000806000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156118d457856000806040805190810160405280600481526020017f4e4f4e450000000000000000000000000000000000000000000000000000000081525091906020604051908101604052806000815250919081915094509450945094509450611af5565b60006118df876143d6565b90506001818154811015156118f057fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018281548110151561193157fe5b906000526020600020906005020160010160018381548110151561195157fe5b906000526020600020906005020160020160018481548110151561197157fe5b90600052602060002090600502016003015460018581548110151561199257fe5b906000526020600020906005020160040160009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611a465780601f10611a1b57610100808354040283529160200191611a46565b820191906000526020600020905b815481529060010190602001808311611a2957829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ae25780601f10611ab757610100808354040283529160200191611ae2565b820191906000526020600020905b815481529060010190602001808311611ac557829003601f168201915b5050505050925095509550955095509550505b91939590929450565b6000600180549050905090565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611b5d5760019050611c8a565b6000611b68856143d6565b9050838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120600182815481101515611bcc57fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015611c695780601f10611c3e57610100808354040283529160200191611c69565b820191906000526020600020905b815481529060010190602001808311611c4c57829003601f168201915b50509250505060405160208183030381529060405280519060200120149150505b9392505050565b60606000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611d18576040805190810160405280600481526020017f4e4f4e45000000000000000000000000000000000000000000000000000000008152509050611e4a565b6000611d23836143d6565b90506000600182815481101515611d3657fe5b906000526020600020906005020160030154141515611e1057600181815481101515611d5e57fe5b90600052602060002090600502016002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611e035780601f10611dd857610100808354040283529160200191611e03565b820191906000526020600020905b815481529060010190602001808311611de657829003601f168201915b5050505050915050611e4a565b6040805190810160405280600481526020017f4e4f4e45000000000000000000000000000000000000000000000000000000008152509150505b919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611ed257600080fd5b505afa158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611faf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050826000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141515156120ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f6163636f756e7420646f6573206e6f742065786973747300000000000000000081525060200191505060405180910390fd5b816040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156120f15780820151818401526020810190506120d6565b50505050905090810190601f16801561211e5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001206001612144836143d6565b81548110151561215057fe5b906000526020600020906005020160010160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121ed5780601f106121c2576101008083540402835291602001916121ed565b820191906000526020600020905b8154815290600101906020018083116121d057829003601f168201915b5050925050506040516020818303038152906040528051906020012014151561227e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6163636f756e7420696e20646966666572656e74206f7267000000000000000081525060200191505060405180910390fd5b60008311801561228e5750600683105b1515612302576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f696e76616c696420737461747573206368616e6765207265717565737400000081525060200191505060405180910390fd5b600115156123658588888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060206040519081016040528060008152506138c5565b1515141515156123c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806147d26031913960400191505060405180910390fd5b6000600184141561245757600260016123d8876143d6565b8154811015156123e457fe5b90600052602060002090600502016003015414151561244e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260398152602001806146fd6039913960400191505060405180910390fd5b600490506126ac565b60028414156124ec576004600161246d876143d6565b81548110151561247957fe5b9060005260206000209060050201600301541415156124e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806146c1603c913960400191505060405180910390fd5b600290506126ab565b60038414156125825760056001612502876143d6565b81548110151561250e57fe5b90600052602060002090600502016003015414151515612579576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806146896038913960400191505060405180910390fd5b600590506126aa565b60048414156126175760056001612598876143d6565b8154811015156125a457fe5b90600052602060002090600502016003015414151561260e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603481526020018061479e6034913960400191505060405180910390fd5b600790506126a9565b60058414156126a8576007600161262d876143d6565b81548110151561263957fe5b9060005260206000209060050201600301541415156126a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806146516038913960400191505060405180910390fd5b600290505b5b5b5b5b8060016126b8876143d6565b8154811015156126c457fe5b9060005260206000209060050201600301819055507f36b0ea38154dec5e98b6bf928b971a9db5e8cd4b6946350e9e43fb9848c70b2585888884604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018381526020018281038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a150505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff1660066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156127e25780820151818401526020810190506127c7565b50505050905090810190601f16801561280f5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561294d57600060066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156128c05780820151818401526020810190506128a5565b50505050905090810190601f1680156128ed5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600261294482614422565b14915050612952565b600090505b919050565b600060608060008060018681548110151561296e57fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166001878154811015156129af57fe5b90600052602060002090600502016001016001888154811015156129cf57fe5b90600052602060002090600502016002016001898154811015156129ef57fe5b90600052602060002090600502016003015460018a815481101515612a1057fe5b906000526020600020906005020160040160009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612ac45780601f10612a9957610100808354040283529160200191612ac4565b820191906000526020600020905b815481529060010190602001808311612aa757829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612b605780601f10612b3557610100808354040283529160200191612b60565b820191906000526020600020905b815481529060010190602001808311612b4357829003601f168201915b505050505092509450945094509450945091939590929450565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015612bff57600080fd5b505afa158015612c13573d6000803e3d6000fd5b505050506040513d6020811015612c2957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6060612ce783611c91565b90506000612cf484614422565b90506000612d01856143d6565b905060056040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612d915780601f10612d6657610100808354040283529160200191612d91565b820191906000526020600020905b815481529060010190602001808311612d7457829003601f168201915b50509250505060405160208183030381529060405280519060200120836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612df1578082015181840152602081019050612dd6565b50505050905090810190601f168015612e1e5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120148015612e465750600182145b15612ef0578460066000898960405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6002600182815481101515612f0157fe5b90600052602060002090600502016003018190555060018082815481101515612f2657fe5b906000526020600020906005020160040160006101000a81548160ff0219169083151502179055507f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc77685600183815481101515612f7f57fe5b9060005260206000209060050201600101600184815481101515612f9f57fe5b9060005260206000209060050201600201600185815481101515612fbf57fe5b906000526020600020906005020160040160009054906101000a900460ff16600186815481101515612fed57fe5b906000526020600020906005020160030154604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001851515151581526020018481526020018381038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130ce5780601f106130a3576101008083540402835291602001916130ce565b820191906000526020600020905b8154815290600101906020018083116130b157829003601f168201915b50508381038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156131515780601f1061312657610100808354040283529160200191613151565b820191906000526020600020905b81548152906001019060200180831161313457829003601f168201915b505097505050505050505060405180910390a1600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156131f25780601f106131c7576101008083540402835291602001916131f2565b820191906000526020600020905b8154815290600101906020018083116131d557829003601f168201915b5050925050506040516020818303038152906040528051906020012060018281548110151561321d57fe5b906000526020600020906005020160020160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156132ba5780601f1061328f576101008083540402835291602001916132ba565b820191906000526020600020905b81548152906001019060200180831161329d57829003601f168201915b505092505050604051602081830303815290604052805190602001201493505050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561336657600080fd5b505afa15801561337a573d6000803e3d6000fd5b505050506040513d602081101561339057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b8383600491906134549291906144ab565b508181600591906134669291906144ab565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156134f057600080fd5b505afa158015613504573d6000803e3d6000fd5b505050506040513d602081101561351a57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156135cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6005604051602001808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561365b5780601f106136305761010080835404028352916020019161365b565b820191906000526020600020905b81548152906001019060200180831161363e57829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014806137d057506004604051602001808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561375f5780601f106137345761010080835404028352916020019161375f565b820191906000526020600020905b81548152906001019060200180831161374257829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120145b1515613827576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806147366028913960400191505060405180910390fd5b6138bd8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846001613ebc565b505050505050565b6000600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139555780601f1061392a57610100808354040283529160200191613955565b820191906000526020600020905b81548152906001019060200180831161393857829003601f168201915b5050925050506040516020818303038152906040528051906020012061397a85611c91565b6040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156139bd5780820151818401526020810190506139a2565b50505050905090810190601f1680156139ea5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001201415613cd1576000613a16856143d6565b9050836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613a5c578082015181840152602081019050613a41565b50505050905090810190601f168015613a895780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120600182815481101515613ab357fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613b505780601f10613b2557610100808354040283529160200191613b50565b820191906000526020600020905b815481529060010190602001808311613b3357829003601f168201915b505092505050604051602081830303815290604052805190602001201480613cc95750826040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613bb7578082015181840152602081019050613b9c565b50505050905090810190601f168015613be45780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120600182815481101515613c0e57fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613cab5780601f10613c8057610100808354040283529160200191613cab565b820191906000526020600020905b815481529060010190602001808311613c8e57829003601f168201915b50509250505060405160208183030381529060405280519060200120145b915050613eb5565b8373ffffffffffffffffffffffffffffffffffffffff1660066000856040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613d30578082015181840152602081019050613d15565b50505050905090810190601f168015613d5d5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480613eb257508373ffffffffffffffffffffffffffffffffffffffff1660066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613e23578082015181840152602081019050613e08565b50505050905090810190601f168015613e505780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b90505b9392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613f3f57600080fd5b505afa158015613f53573d6000803e3d6000fd5b505050506040513d6020811015613f6957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561401c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000614027866143d6565b90506000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141515614109578360018281548110151561408257fe5b906000526020600020906005020160020190805190602001906140a692919061452b565b50826001828154811015156140b757fe5b906000526020600020906005020160030181905550816001828154811015156140dc57fe5b906000526020600020906005020160040160006101000a81548160ff02191690831515021790555061427d565b600360008154809291906001019190505550600354600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600160a0604051908101604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018781526020018681526020018581526020018415158152509080600181540180825580915050906001820390600052602060002090600502016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190805190602001906142319291906145ab565b50604082015181600201908051906020019061424e9291906145ab565b506060820151816003015560808201518160040160006101000a81548160ff0219169083151502179055505050505b7f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc7768686868587604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b8381101561432957808201518184015260208101905061430e565b50505050905090810190601f1680156143565780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b8381101561438f578082015181840152602081019050614374565b50505050905090810190601f1680156143bc5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a1505050505050565b60006001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054039050919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561447457600090506144a6565b600061447f836143d6565b905060018181548110151561449057fe5b9060005260206000209060050201600301549150505b919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106144ec57803560ff191683800117855561451a565b8280016001018555821561451a579182015b828111156145195782358255916020019190600101906144fe565b5b509050614527919061462b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061456c57805160ff191683800117855561459a565b8280016001018555821561459a579182015b8281111561459957825182559160200191906001019061457e565b5b5090506145a7919061462b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145ec57805160ff191683800117855561461a565b8280016001018555821561461a579182015b828111156146195782518255916020019190600101906145fe565b5b509050614627919061462b565b5090565b61464d91905b80821115614649576000816000905550600101614631565b5090565b9056fe6163636f756e74207265636f76657279206e6f7420696e697469617465642e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e7420697320616c726561647920626c61636b6c69737465642e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e74206973206e6f7420696e2073757370656e646564207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e74206973206e6f7420696e20616374697665207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e6563616e2062652063616c6c656420746f2061737369676e2061646d696e20726f6c6573206f6e6c7963616e6e6f742062652063616c6c65642066726f2061737369676e696e67206f72672061646d696e20616e64206e6574776f726b2061646d696e20726f6c65736163636f756e74206973206e6f7420626c61636b6c69737465642e206f7065726174696f6e2063616e6e6f7420626520646f6e65737461747573206368616e6765206e6f7420706f737369626c6520666f72206f72672061646d696e206163636f756e7473a165627a7a72305820a534fbde5dac7e84dd47dee87465cfb80f5dc4b2409ed9c4e52bced609423e980029` + +// DeployAcctManager deploys a new Ethereum contract, binding an instance of AcctManager to it. +func DeployAcctManager(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address) (common.Address, *types.Transaction, *AcctManager, error) { + parsed, err := abi.JSON(strings.NewReader(AcctManagerABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(AcctManagerBin), backend, _permUpgradable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AcctManager{AcctManagerCaller: AcctManagerCaller{contract: contract}, AcctManagerTransactor: AcctManagerTransactor{contract: contract}, AcctManagerFilterer: AcctManagerFilterer{contract: contract}}, nil +} + +// AcctManager is an auto generated Go binding around an Ethereum contract. +type AcctManager struct { + AcctManagerCaller // Read-only binding to the contract + AcctManagerTransactor // Write-only binding to the contract + AcctManagerFilterer // Log filterer for contract events +} + +// AcctManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type AcctManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AcctManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AcctManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AcctManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AcctManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AcctManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AcctManagerSession struct { + Contract *AcctManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AcctManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AcctManagerCallerSession struct { + Contract *AcctManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AcctManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AcctManagerTransactorSession struct { + Contract *AcctManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AcctManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type AcctManagerRaw struct { + Contract *AcctManager // Generic contract binding to access the raw methods on +} + +// AcctManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AcctManagerCallerRaw struct { + Contract *AcctManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// AcctManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AcctManagerTransactorRaw struct { + Contract *AcctManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAcctManager creates a new instance of AcctManager, bound to a specific deployed contract. +func NewAcctManager(address common.Address, backend bind.ContractBackend) (*AcctManager, error) { + contract, err := bindAcctManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AcctManager{AcctManagerCaller: AcctManagerCaller{contract: contract}, AcctManagerTransactor: AcctManagerTransactor{contract: contract}, AcctManagerFilterer: AcctManagerFilterer{contract: contract}}, nil +} + +// NewAcctManagerCaller creates a new read-only instance of AcctManager, bound to a specific deployed contract. +func NewAcctManagerCaller(address common.Address, caller bind.ContractCaller) (*AcctManagerCaller, error) { + contract, err := bindAcctManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AcctManagerCaller{contract: contract}, nil +} + +// NewAcctManagerTransactor creates a new write-only instance of AcctManager, bound to a specific deployed contract. +func NewAcctManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AcctManagerTransactor, error) { + contract, err := bindAcctManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AcctManagerTransactor{contract: contract}, nil +} + +// NewAcctManagerFilterer creates a new log filterer instance of AcctManager, bound to a specific deployed contract. +func NewAcctManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AcctManagerFilterer, error) { + contract, err := bindAcctManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AcctManagerFilterer{contract: contract}, nil +} + +// bindAcctManager binds a generic wrapper to an already deployed contract. +func bindAcctManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AcctManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AcctManager *AcctManagerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _AcctManager.Contract.AcctManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AcctManager *AcctManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AcctManager.Contract.AcctManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AcctManager *AcctManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AcctManager.Contract.AcctManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AcctManager *AcctManagerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _AcctManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AcctManager *AcctManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AcctManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AcctManager *AcctManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AcctManager.Contract.contract.Transact(opts, method, params...) +} + +// CheckOrgAdmin is a free data retrieval call binding the contract method 0xe8b42bf4. +// +// Solidity: function checkOrgAdmin(_account address, _orgId string, _ultParent string) constant returns(bool) +func (_AcctManager *AcctManagerCaller) CheckOrgAdmin(opts *bind.CallOpts, _account common.Address, _orgId string, _ultParent string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _AcctManager.contract.Call(opts, out, "checkOrgAdmin", _account, _orgId, _ultParent) + return *ret0, err +} + +// CheckOrgAdmin is a free data retrieval call binding the contract method 0xe8b42bf4. +// +// Solidity: function checkOrgAdmin(_account address, _orgId string, _ultParent string) constant returns(bool) +func (_AcctManager *AcctManagerSession) CheckOrgAdmin(_account common.Address, _orgId string, _ultParent string) (bool, error) { + return _AcctManager.Contract.CheckOrgAdmin(&_AcctManager.CallOpts, _account, _orgId, _ultParent) +} + +// CheckOrgAdmin is a free data retrieval call binding the contract method 0xe8b42bf4. +// +// Solidity: function checkOrgAdmin(_account address, _orgId string, _ultParent string) constant returns(bool) +func (_AcctManager *AcctManagerCallerSession) CheckOrgAdmin(_account common.Address, _orgId string, _ultParent string) (bool, error) { + return _AcctManager.Contract.CheckOrgAdmin(&_AcctManager.CallOpts, _account, _orgId, _ultParent) +} + +// GetAccountDetails is a free data retrieval call binding the contract method 0x2aceb534. +// +// Solidity: function getAccountDetails(_account address) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerCaller) GetAccountDetails(opts *bind.CallOpts, _account common.Address) (common.Address, string, string, *big.Int, bool, error) { + var ( + ret0 = new(common.Address) + ret1 = new(string) + ret2 = new(string) + ret3 = new(*big.Int) + ret4 = new(bool) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + ret4, + } + err := _AcctManager.contract.Call(opts, out, "getAccountDetails", _account) + return *ret0, *ret1, *ret2, *ret3, *ret4, err +} + +// GetAccountDetails is a free data retrieval call binding the contract method 0x2aceb534. +// +// Solidity: function getAccountDetails(_account address) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerSession) GetAccountDetails(_account common.Address) (common.Address, string, string, *big.Int, bool, error) { + return _AcctManager.Contract.GetAccountDetails(&_AcctManager.CallOpts, _account) +} + +// GetAccountDetails is a free data retrieval call binding the contract method 0x2aceb534. +// +// Solidity: function getAccountDetails(_account address) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerCallerSession) GetAccountDetails(_account common.Address) (common.Address, string, string, *big.Int, bool, error) { + return _AcctManager.Contract.GetAccountDetails(&_AcctManager.CallOpts, _account) +} + +// GetAccountDetailsFromIndex is a free data retrieval call binding the contract method 0xb2018568. +// +// Solidity: function getAccountDetailsFromIndex(_aIndex uint256) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerCaller) GetAccountDetailsFromIndex(opts *bind.CallOpts, _aIndex *big.Int) (common.Address, string, string, *big.Int, bool, error) { + var ( + ret0 = new(common.Address) + ret1 = new(string) + ret2 = new(string) + ret3 = new(*big.Int) + ret4 = new(bool) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + ret4, + } + err := _AcctManager.contract.Call(opts, out, "getAccountDetailsFromIndex", _aIndex) + return *ret0, *ret1, *ret2, *ret3, *ret4, err +} + +// GetAccountDetailsFromIndex is a free data retrieval call binding the contract method 0xb2018568. +// +// Solidity: function getAccountDetailsFromIndex(_aIndex uint256) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerSession) GetAccountDetailsFromIndex(_aIndex *big.Int) (common.Address, string, string, *big.Int, bool, error) { + return _AcctManager.Contract.GetAccountDetailsFromIndex(&_AcctManager.CallOpts, _aIndex) +} + +// GetAccountDetailsFromIndex is a free data retrieval call binding the contract method 0xb2018568. +// +// Solidity: function getAccountDetailsFromIndex(_aIndex uint256) constant returns(address, string, string, uint256, bool) +func (_AcctManager *AcctManagerCallerSession) GetAccountDetailsFromIndex(_aIndex *big.Int) (common.Address, string, string, *big.Int, bool, error) { + return _AcctManager.Contract.GetAccountDetailsFromIndex(&_AcctManager.CallOpts, _aIndex) +} + +// GetAccountRole is a free data retrieval call binding the contract method 0x81d66b23. +// +// Solidity: function getAccountRole(_account address) constant returns(string) +func (_AcctManager *AcctManagerCaller) GetAccountRole(opts *bind.CallOpts, _account common.Address) (string, error) { + var ( + ret0 = new(string) + ) + out := ret0 + err := _AcctManager.contract.Call(opts, out, "getAccountRole", _account) + return *ret0, err +} + +// GetAccountRole is a free data retrieval call binding the contract method 0x81d66b23. +// +// Solidity: function getAccountRole(_account address) constant returns(string) +func (_AcctManager *AcctManagerSession) GetAccountRole(_account common.Address) (string, error) { + return _AcctManager.Contract.GetAccountRole(&_AcctManager.CallOpts, _account) +} + +// GetAccountRole is a free data retrieval call binding the contract method 0x81d66b23. +// +// Solidity: function getAccountRole(_account address) constant returns(string) +func (_AcctManager *AcctManagerCallerSession) GetAccountRole(_account common.Address) (string, error) { + return _AcctManager.Contract.GetAccountRole(&_AcctManager.CallOpts, _account) +} + +// GetNumberOfAccounts is a free data retrieval call binding the contract method 0x309e36ef. +// +// Solidity: function getNumberOfAccounts() constant returns(uint256) +func (_AcctManager *AcctManagerCaller) GetNumberOfAccounts(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _AcctManager.contract.Call(opts, out, "getNumberOfAccounts") + return *ret0, err +} + +// GetNumberOfAccounts is a free data retrieval call binding the contract method 0x309e36ef. +// +// Solidity: function getNumberOfAccounts() constant returns(uint256) +func (_AcctManager *AcctManagerSession) GetNumberOfAccounts() (*big.Int, error) { + return _AcctManager.Contract.GetNumberOfAccounts(&_AcctManager.CallOpts) +} + +// GetNumberOfAccounts is a free data retrieval call binding the contract method 0x309e36ef. +// +// Solidity: function getNumberOfAccounts() constant returns(uint256) +func (_AcctManager *AcctManagerCallerSession) GetNumberOfAccounts() (*big.Int, error) { + return _AcctManager.Contract.GetNumberOfAccounts(&_AcctManager.CallOpts) +} + +// OrgAdminExists is a free data retrieval call binding the contract method 0x950145cf. +// +// Solidity: function orgAdminExists(_orgId string) constant returns(bool) +func (_AcctManager *AcctManagerCaller) OrgAdminExists(opts *bind.CallOpts, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _AcctManager.contract.Call(opts, out, "orgAdminExists", _orgId) + return *ret0, err +} + +// OrgAdminExists is a free data retrieval call binding the contract method 0x950145cf. +// +// Solidity: function orgAdminExists(_orgId string) constant returns(bool) +func (_AcctManager *AcctManagerSession) OrgAdminExists(_orgId string) (bool, error) { + return _AcctManager.Contract.OrgAdminExists(&_AcctManager.CallOpts, _orgId) +} + +// OrgAdminExists is a free data retrieval call binding the contract method 0x950145cf. +// +// Solidity: function orgAdminExists(_orgId string) constant returns(bool) +func (_AcctManager *AcctManagerCallerSession) OrgAdminExists(_orgId string) (bool, error) { + return _AcctManager.Contract.OrgAdminExists(&_AcctManager.CallOpts, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_AcctManager *AcctManagerCaller) ValidateAccount(opts *bind.CallOpts, _account common.Address, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _AcctManager.contract.Call(opts, out, "validateAccount", _account, _orgId) + return *ret0, err +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_AcctManager *AcctManagerSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _AcctManager.Contract.ValidateAccount(&_AcctManager.CallOpts, _account, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_AcctManager *AcctManagerCallerSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _AcctManager.Contract.ValidateAccount(&_AcctManager.CallOpts, _account, _orgId) +} + +// AddNewAdmin is a paid mutator transaction binding the contract method 0xc214e5e5. +// +// Solidity: function addNewAdmin(_orgId string, _account address) returns(voterUpdate bool) +func (_AcctManager *AcctManagerTransactor) AddNewAdmin(opts *bind.TransactOpts, _orgId string, _account common.Address) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "addNewAdmin", _orgId, _account) +} + +// AddNewAdmin is a paid mutator transaction binding the contract method 0xc214e5e5. +// +// Solidity: function addNewAdmin(_orgId string, _account address) returns(voterUpdate bool) +func (_AcctManager *AcctManagerSession) AddNewAdmin(_orgId string, _account common.Address) (*types.Transaction, error) { + return _AcctManager.Contract.AddNewAdmin(&_AcctManager.TransactOpts, _orgId, _account) +} + +// AddNewAdmin is a paid mutator transaction binding the contract method 0xc214e5e5. +// +// Solidity: function addNewAdmin(_orgId string, _account address) returns(voterUpdate bool) +func (_AcctManager *AcctManagerTransactorSession) AddNewAdmin(_orgId string, _account common.Address) (*types.Transaction, error) { + return _AcctManager.Contract.AddNewAdmin(&_AcctManager.TransactOpts, _orgId, _account) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x143a5604. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _adminRole bool) returns() +func (_AcctManager *AcctManagerTransactor) AssignAccountRole(opts *bind.TransactOpts, _account common.Address, _orgId string, _roleId string, _adminRole bool) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "assignAccountRole", _account, _orgId, _roleId, _adminRole) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x143a5604. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _adminRole bool) returns() +func (_AcctManager *AcctManagerSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string, _adminRole bool) (*types.Transaction, error) { + return _AcctManager.Contract.AssignAccountRole(&_AcctManager.TransactOpts, _account, _orgId, _roleId, _adminRole) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x143a5604. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _adminRole bool) returns() +func (_AcctManager *AcctManagerTransactorSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string, _adminRole bool) (*types.Transaction, error) { + return _AcctManager.Contract.AssignAccountRole(&_AcctManager.TransactOpts, _account, _orgId, _roleId, _adminRole) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0xe3483a9d. +// +// Solidity: function assignAdminRole(_account address, _orgId string, _roleId string, _status uint256) returns() +func (_AcctManager *AcctManagerTransactor) AssignAdminRole(opts *bind.TransactOpts, _account common.Address, _orgId string, _roleId string, _status *big.Int) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "assignAdminRole", _account, _orgId, _roleId, _status) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0xe3483a9d. +// +// Solidity: function assignAdminRole(_account address, _orgId string, _roleId string, _status uint256) returns() +func (_AcctManager *AcctManagerSession) AssignAdminRole(_account common.Address, _orgId string, _roleId string, _status *big.Int) (*types.Transaction, error) { + return _AcctManager.Contract.AssignAdminRole(&_AcctManager.TransactOpts, _account, _orgId, _roleId, _status) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0xe3483a9d. +// +// Solidity: function assignAdminRole(_account address, _orgId string, _roleId string, _status uint256) returns() +func (_AcctManager *AcctManagerTransactorSession) AssignAdminRole(_account common.Address, _orgId string, _roleId string, _status *big.Int) (*types.Transaction, error) { + return _AcctManager.Contract.AssignAdminRole(&_AcctManager.TransactOpts, _account, _orgId, _roleId, _status) +} + +// RemoveExistingAdmin is a paid mutator transaction binding the contract method 0x1d09dc93. +// +// Solidity: function removeExistingAdmin(_orgId string) returns(voterUpdate bool, account address) +func (_AcctManager *AcctManagerTransactor) RemoveExistingAdmin(opts *bind.TransactOpts, _orgId string) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "removeExistingAdmin", _orgId) +} + +// RemoveExistingAdmin is a paid mutator transaction binding the contract method 0x1d09dc93. +// +// Solidity: function removeExistingAdmin(_orgId string) returns(voterUpdate bool, account address) +func (_AcctManager *AcctManagerSession) RemoveExistingAdmin(_orgId string) (*types.Transaction, error) { + return _AcctManager.Contract.RemoveExistingAdmin(&_AcctManager.TransactOpts, _orgId) +} + +// RemoveExistingAdmin is a paid mutator transaction binding the contract method 0x1d09dc93. +// +// Solidity: function removeExistingAdmin(_orgId string) returns(voterUpdate bool, account address) +func (_AcctManager *AcctManagerTransactorSession) RemoveExistingAdmin(_orgId string) (*types.Transaction, error) { + return _AcctManager.Contract.RemoveExistingAdmin(&_AcctManager.TransactOpts, _orgId) +} + +// SetDefaults is a paid mutator transaction binding the contract method 0xcef7f6af. +// +// Solidity: function setDefaults(_nwAdminRole string, _oAdminRole string) returns() +func (_AcctManager *AcctManagerTransactor) SetDefaults(opts *bind.TransactOpts, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "setDefaults", _nwAdminRole, _oAdminRole) +} + +// SetDefaults is a paid mutator transaction binding the contract method 0xcef7f6af. +// +// Solidity: function setDefaults(_nwAdminRole string, _oAdminRole string) returns() +func (_AcctManager *AcctManagerSession) SetDefaults(_nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _AcctManager.Contract.SetDefaults(&_AcctManager.TransactOpts, _nwAdminRole, _oAdminRole) +} + +// SetDefaults is a paid mutator transaction binding the contract method 0xcef7f6af. +// +// Solidity: function setDefaults(_nwAdminRole string, _oAdminRole string) returns() +func (_AcctManager *AcctManagerTransactorSession) SetDefaults(_nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _AcctManager.Contract.SetDefaults(&_AcctManager.TransactOpts, _nwAdminRole, _oAdminRole) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_AcctManager *AcctManagerTransactor) UpdateAccountStatus(opts *bind.TransactOpts, _orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _AcctManager.contract.Transact(opts, "updateAccountStatus", _orgId, _account, _action) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_AcctManager *AcctManagerSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _AcctManager.Contract.UpdateAccountStatus(&_AcctManager.TransactOpts, _orgId, _account, _action) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_AcctManager *AcctManagerTransactorSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _AcctManager.Contract.UpdateAccountStatus(&_AcctManager.TransactOpts, _orgId, _account, _action) +} + +// AcctManagerAccountAccessModifiedIterator is returned from FilterAccountAccessModified and is used to iterate over the raw logs and unpacked data for AccountAccessModified events raised by the AcctManager contract. +type AcctManagerAccountAccessModifiedIterator struct { + Event *AcctManagerAccountAccessModified // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AcctManagerAccountAccessModifiedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountAccessModified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountAccessModified) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AcctManagerAccountAccessModifiedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AcctManagerAccountAccessModifiedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AcctManagerAccountAccessModified represents a AccountAccessModified event raised by the AcctManager contract. +type AcctManagerAccountAccessModified struct { + Account common.Address + OrgId string + RoleId string + OrgAdmin bool + Status *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAccountAccessModified is a free log retrieval operation binding the contract event 0x68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc776. +// +// Solidity: e AccountAccessModified(_account address, _orgId string, _roleId string, _orgAdmin bool, _status uint256) +func (_AcctManager *AcctManagerFilterer) FilterAccountAccessModified(opts *bind.FilterOpts) (*AcctManagerAccountAccessModifiedIterator, error) { + + logs, sub, err := _AcctManager.contract.FilterLogs(opts, "AccountAccessModified") + if err != nil { + return nil, err + } + return &AcctManagerAccountAccessModifiedIterator{contract: _AcctManager.contract, event: "AccountAccessModified", logs: logs, sub: sub}, nil +} + +// WatchAccountAccessModified is a free log subscription operation binding the contract event 0x68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc776. +// +// Solidity: e AccountAccessModified(_account address, _orgId string, _roleId string, _orgAdmin bool, _status uint256) +func (_AcctManager *AcctManagerFilterer) WatchAccountAccessModified(opts *bind.WatchOpts, sink chan<- *AcctManagerAccountAccessModified) (event.Subscription, error) { + + logs, sub, err := _AcctManager.contract.WatchLogs(opts, "AccountAccessModified") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AcctManagerAccountAccessModified) + if err := _AcctManager.contract.UnpackLog(event, "AccountAccessModified", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// AcctManagerAccountAccessRevokedIterator is returned from FilterAccountAccessRevoked and is used to iterate over the raw logs and unpacked data for AccountAccessRevoked events raised by the AcctManager contract. +type AcctManagerAccountAccessRevokedIterator struct { + Event *AcctManagerAccountAccessRevoked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AcctManagerAccountAccessRevokedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountAccessRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountAccessRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AcctManagerAccountAccessRevokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AcctManagerAccountAccessRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AcctManagerAccountAccessRevoked represents a AccountAccessRevoked event raised by the AcctManager contract. +type AcctManagerAccountAccessRevoked struct { + Account common.Address + OrgId string + RoleId string + OrgAdmin bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAccountAccessRevoked is a free log retrieval operation binding the contract event 0x6b5105396435a8a139aeed682dd573cd2a7e6279de77f8c11f95a30399212ad1. +// +// Solidity: e AccountAccessRevoked(_account address, _orgId string, _roleId string, _orgAdmin bool) +func (_AcctManager *AcctManagerFilterer) FilterAccountAccessRevoked(opts *bind.FilterOpts) (*AcctManagerAccountAccessRevokedIterator, error) { + + logs, sub, err := _AcctManager.contract.FilterLogs(opts, "AccountAccessRevoked") + if err != nil { + return nil, err + } + return &AcctManagerAccountAccessRevokedIterator{contract: _AcctManager.contract, event: "AccountAccessRevoked", logs: logs, sub: sub}, nil +} + +// WatchAccountAccessRevoked is a free log subscription operation binding the contract event 0x6b5105396435a8a139aeed682dd573cd2a7e6279de77f8c11f95a30399212ad1. +// +// Solidity: e AccountAccessRevoked(_account address, _orgId string, _roleId string, _orgAdmin bool) +func (_AcctManager *AcctManagerFilterer) WatchAccountAccessRevoked(opts *bind.WatchOpts, sink chan<- *AcctManagerAccountAccessRevoked) (event.Subscription, error) { + + logs, sub, err := _AcctManager.contract.WatchLogs(opts, "AccountAccessRevoked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AcctManagerAccountAccessRevoked) + if err := _AcctManager.contract.UnpackLog(event, "AccountAccessRevoked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// AcctManagerAccountStatusChangedIterator is returned from FilterAccountStatusChanged and is used to iterate over the raw logs and unpacked data for AccountStatusChanged events raised by the AcctManager contract. +type AcctManagerAccountStatusChangedIterator struct { + Event *AcctManagerAccountStatusChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *AcctManagerAccountStatusChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountStatusChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(AcctManagerAccountStatusChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *AcctManagerAccountStatusChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *AcctManagerAccountStatusChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// AcctManagerAccountStatusChanged represents a AccountStatusChanged event raised by the AcctManager contract. +type AcctManagerAccountStatusChanged struct { + Account common.Address + OrgId string + Status *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAccountStatusChanged is a free log retrieval operation binding the contract event 0x36b0ea38154dec5e98b6bf928b971a9db5e8cd4b6946350e9e43fb9848c70b25. +// +// Solidity: e AccountStatusChanged(_account address, _orgId string, _status uint256) +func (_AcctManager *AcctManagerFilterer) FilterAccountStatusChanged(opts *bind.FilterOpts) (*AcctManagerAccountStatusChangedIterator, error) { + + logs, sub, err := _AcctManager.contract.FilterLogs(opts, "AccountStatusChanged") + if err != nil { + return nil, err + } + return &AcctManagerAccountStatusChangedIterator{contract: _AcctManager.contract, event: "AccountStatusChanged", logs: logs, sub: sub}, nil +} + +// WatchAccountStatusChanged is a free log subscription operation binding the contract event 0x36b0ea38154dec5e98b6bf928b971a9db5e8cd4b6946350e9e43fb9848c70b25. +// +// Solidity: e AccountStatusChanged(_account address, _orgId string, _status uint256) +func (_AcctManager *AcctManagerFilterer) WatchAccountStatusChanged(opts *bind.WatchOpts, sink chan<- *AcctManagerAccountStatusChanged) (event.Subscription, error) { + + logs, sub, err := _AcctManager.contract.WatchLogs(opts, "AccountStatusChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(AcctManagerAccountStatusChanged) + if err := _AcctManager.contract.UnpackLog(event, "AccountStatusChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/bind/nodes.go b/permission/bind/nodes.go new file mode 100644 index 0000000000..9b0983bc80 --- /dev/null +++ b/permission/bind/nodes.go @@ -0,0 +1,1261 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// NodeManagerABI is the input ABI used to generate the binding from. +const NodeManagerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateNodeStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"enodeId\",\"type\":\"string\"}],\"name\":\"getNodeDetails\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addOrgNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"approveNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_nodeIndex\",\"type\":\"uint256\"}],\"name\":\"getNodeDetailsFromIndex\",\"outputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_nodeStatus\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfNodes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addAdminNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeBlacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeRecoveryInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_enodeId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"NodeRecoveryCompleted\",\"type\":\"event\"}]" + +// NodeManagerBin is the compiled bytecode used for deploying new contracts. +const NodeManagerBin = `608060405234801561001057600080fd5b506040516020806131c18339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613130806100916000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c01000000000000000000000000000000000000000000000000000000009004806397c07a9b1161007857806397c07a9b14610483578063a97a44061461059d578063b81c806a1461066b578063e3b09d8414610689576100a5565b80630cc50146146100aa5780633f0e0e47146101825780633f5e1a45146102e757806386bc3652146103b5575b600080fd5b610180600480360360608110156100c057600080fd5b81019080803590602001906401000000008111156100dd57600080fd5b8201836020820111156100ef57600080fd5b8035906020019184600183028401116401000000008311171561011157600080fd5b90919293919293908035906020019064010000000081111561013257600080fd5b82018360208201111561014457600080fd5b8035906020019184600183028401116401000000008311171561016657600080fd5b909192939192939080359060200190929190505050610757565b005b6101f96004803603602081101561019857600080fd5b81019080803590602001906401000000008111156101b557600080fd5b8201836020820111156101c757600080fd5b803590602001918460018302840111640100000000831117156101e957600080fd5b9091929391929390505050611404565b604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b83811015610243578082015181840152602081019050610228565b50505050905090810190601f1680156102705780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156102a957808201518184015260208101905061028e565b50505050905090810190601f1680156102d65780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b6103b3600480360360408110156102fd57600080fd5b810190808035906020019064010000000081111561031a57600080fd5b82018360208201111561032c57600080fd5b8035906020019184600183028401116401000000008311171561034e57600080fd5b90919293919293908035906020019064010000000081111561036f57600080fd5b82018360208201111561038157600080fd5b803590602001918460018302840111640100000000831117156103a357600080fd5b9091929391929390505050611600565b005b610481600480360360408110156103cb57600080fd5b81019080803590602001906401000000008111156103e857600080fd5b8201836020820111156103fa57600080fd5b8035906020019184600183028401116401000000008311171561041c57600080fd5b90919293919293908035906020019064010000000081111561043d57600080fd5b82018360208201111561044f57600080fd5b8035906020019184600183028401116401000000008311171561047157600080fd5b9091929391929390505050611af0565b005b6104af6004803603602081101561049957600080fd5b8101908080359060200190929190505050612159565b604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156104f95780820151818401526020810190506104de565b50505050905090810190601f1680156105265780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561055f578082015181840152602081019050610544565b50505050905090810190601f16801561058c5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b610669600480360360408110156105b357600080fd5b81019080803590602001906401000000008111156105d057600080fd5b8201836020820111156105e257600080fd5b8035906020019184600183028401116401000000008311171561060457600080fd5b90919293919293908035906020019064010000000081111561062557600080fd5b82018360208201111561063757600080fd5b8035906020019184600183028401116401000000008311171561065957600080fd5b9091929391929390505050612304565b005b6106736127f4565b6040518082815260200191505060405180910390f35b6107556004803603604081101561069f57600080fd5b81019080803590602001906401000000008111156106bc57600080fd5b8201836020820111156106ce57600080fd5b803590602001918460018302840111640100000000831117156106f057600080fd5b90919293919293908035906020019064010000000081111561071157600080fd5b82018360208201111561072357600080fd5b8035906020019184600183028401116401000000008311171561074557600080fd5b90919293919293905050506127fe565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156107da57600080fd5b505afa1580156107ee573d6000803e3d6000fd5b505050506040513d602081101561080457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561094657808201518184015260208101905061092b565b50505050905090810190601f1680156109735780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012081526020019081526020016000205414151515610a13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f70617373656420656e6f646520696420646f6573206e6f74206578697374000081525060200191505060405180910390fd5b610aa586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612cee565b1515610afc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613088602a913960400191505060405180910390fd5b6001821480610b0b5750600282145b80610b165750600382145b80610b215750600482145b80610b2c5750600582145b1515610b83576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806130b26026913960400191505060405180910390fd5b6001821415610d5e576002610bdb87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515610c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60036001610ca188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610cad57fe5b9060005260206000209060030201600201819055507fc6c3720fe673e87bb26e06be713d514278aa94c3939cfe7c64b9bea4d486824a868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fc565b6002821415610f39576003610db687878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60026001610e7c88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610e8857fe5b9060005260206000209060030201600201819055507f49796be3ca168a59c8ae46c75a36a9bb3a84753d3e12a812f93ae010e783b14f868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fb565b60038214156110505760046001610f9388888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610f9f57fe5b9060005260206000209060030201600201819055507f4714623279994517c446c8fb72c3fdaca26434da1e2490d3976fe0cd880cfa7a868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fa565b600482141561122b5760046110a887878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b14151561111d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6005600161116e88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b81548110151561117a57fe5b9060005260206000209060030201600201819055507ffd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113f9565b600561127a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b1415156112ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6002600161134088888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b81548110151561134c57fe5b9060005260206000209060030201600201819055507f787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15b5b5b5b505050505050565b60608060008061145786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b905060018181548110151561146857fe5b906000526020600020906003020160010160018281548110151561148857fe5b90600052602060002090600302016000016001838154811015156114a857fe5b906000526020600020906003020160020154828054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561154f5780601f106115245761010080835404028352916020019161154f565b820191906000526020600020905b81548152906001019060200180831161153257829003601f168201915b50505050509250818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115eb5780601f106115c0576101008083540402835291602001916115eb565b820191906000526020600020905b8154815290600101906020018083116115ce57829003601f168201915b50505050509150935093509350509250925092565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561168357600080fd5b505afa158015611697573d6000803e3d6000fd5b505050506040513d60208110156116ad57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156117ef5780820151818401526020810190506117d4565b50505050905090810190601f16801561181c5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016002815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000019080519060200190611a27929190612fe2565b506020820151816001019080519060200190611a44929190612fe2565b50604082015181600201555050507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611b7357600080fd5b505afa158015611b87573d6000803e3d6000fd5b505050506040513d6020811015611b9d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015611cdf578082015181840152602081019050611cc4565b50505050905090810190601f168015611d0c5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012081526020019081526020016000205414151515611dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f70617373656420656e6f646520696420646f6573206e6f74206578697374000081525060200191505060405180910390fd5b611e3e85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612cee565b1515611e95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806130d8602d913960400191505060405180910390fd5b6001611ee486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515611f59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6e6f7468696e672070656e64696e6720666f7220617070726f76616c0000000081525060200191505060405180910390fd5b6000611fa886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b90506002600182815481101515611fbb57fe5b9060005260206000209060030201600201819055507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d60018281548110151561200057fe5b906000526020600020906003020160000160018381548110151561202057fe5b90600052602060002090600302016001016040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156120be5780601f10612093576101008083540402835291602001916120be565b820191906000526020600020905b8154815290600101906020018083116120a157829003601f168201915b50508381038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121415780601f1061211657610100808354040283529160200191612141565b820191906000526020600020905b81548152906001019060200180831161212457829003601f168201915b505094505050505060405180910390a1505050505050565b606080600060018481548110151561216d57fe5b906000526020600020906003020160010160018581548110151561218d57fe5b90600052602060002090600302016000016001868154811015156121ad57fe5b906000526020600020906003020160020154828054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156122545780601f1061222957610100808354040283529160200191612254565b820191906000526020600020905b81548152906001019060200180831161223757829003601f168201915b50505050509250818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156122f05780601f106122c5576101008083540402835291602001916122f0565b820191906000526020600020905b8154815290600101906020018083116122d357829003601f168201915b505050505091509250925092509193909250565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561238757600080fd5b505afa15801561239b573d6000803e3d6000fd5b505050506040513d60208110156123b157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612464576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156124f35780820151818401526020810190506124d8565b50505050905090810190601f1680156125205780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415156125bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508152602001600181525090806001815401808255809150509060018203906000526020600020906003020160009091929091909150600082015181600001908051906020019061272b929190612fe2565b506020820151816001019080519060200190612748929190612fe2565b50604082015181600201555050507fb1a7eec7dd1a516c3132d6d1f770758b19aa34c3a07c138caf662688b7e3556f858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000600354905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561288157600080fd5b505afa158015612895573d6000803e3d6000fd5b505050506040513d60208110156128ab57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561295e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156129ed5780820151818401526020810190506129d2565b50505050905090810190601f168015612a1a5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054141515612ab9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016002815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000019080519060200190612c25929190612fe2565b506020820151816001019080519060200190612c42929190612fe2565b50604082015181600201555050507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000816040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612d34578082015181840152602081019050612d19565b50505050905090810190601f168015612d615780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001206001612d8785612f37565b815481101515612d9357fe5b90600052602060002090600302016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612e305780601f10612e0557610100808354040283529160200191612e30565b820191906000526020600020905b815481529060010190602001808311612e1357829003601f168201915b5050925050506040516020818303038152906040528051906020012014905092915050565b60008060026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612ea0578082015181840152602081019050612e85565b50505050905090810190601f168015612ecd5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415612f065760009050612f32565b6001612f1183612f37565b815481101515612f1d57fe5b90600052602060002090600302016002015490505b919050565b6000600160026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612f83578082015181840152602081019050612f68565b50505050905090810190601f168015612fb05780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061302357805160ff1916838001178555613051565b82800160010185558215613051579182015b82811115613050578251825591602001919060010190613035565b5b50905061305e9190613062565b5090565b61308491905b80821115613080576000816000905550600101613068565b5090565b9056fe656e6f646520696420646f6573206e6f742062656c6f6e6720746f2074686520706173736564206f7267696e76616c6964206f7065726174696f6e2e2077726f6e6720616374696f6e20706173736564656e6f646520696420646f6573206e6f742062656c6f6e6720746f2074686520706173736564206f7267206964a165627a7a7230582011179f2b111ff0fc199ae5bdfe206abf5283b1c344d947e24ad65df0e432745e0029` + +// DeployNodeManager deploys a new Ethereum contract, binding an instance of NodeManager to it. +func DeployNodeManager(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address) (common.Address, *types.Transaction, *NodeManager, error) { + parsed, err := abi.JSON(strings.NewReader(NodeManagerABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(NodeManagerBin), backend, _permUpgradable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NodeManager{NodeManagerCaller: NodeManagerCaller{contract: contract}, NodeManagerTransactor: NodeManagerTransactor{contract: contract}, NodeManagerFilterer: NodeManagerFilterer{contract: contract}}, nil +} + +// NodeManager is an auto generated Go binding around an Ethereum contract. +type NodeManager struct { + NodeManagerCaller // Read-only binding to the contract + NodeManagerTransactor // Write-only binding to the contract + NodeManagerFilterer // Log filterer for contract events +} + +// NodeManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type NodeManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NodeManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NodeManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NodeManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NodeManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NodeManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NodeManagerSession struct { + Contract *NodeManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NodeManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NodeManagerCallerSession struct { + Contract *NodeManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NodeManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NodeManagerTransactorSession struct { + Contract *NodeManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NodeManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type NodeManagerRaw struct { + Contract *NodeManager // Generic contract binding to access the raw methods on +} + +// NodeManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NodeManagerCallerRaw struct { + Contract *NodeManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// NodeManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NodeManagerTransactorRaw struct { + Contract *NodeManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNodeManager creates a new instance of NodeManager, bound to a specific deployed contract. +func NewNodeManager(address common.Address, backend bind.ContractBackend) (*NodeManager, error) { + contract, err := bindNodeManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NodeManager{NodeManagerCaller: NodeManagerCaller{contract: contract}, NodeManagerTransactor: NodeManagerTransactor{contract: contract}, NodeManagerFilterer: NodeManagerFilterer{contract: contract}}, nil +} + +// NewNodeManagerCaller creates a new read-only instance of NodeManager, bound to a specific deployed contract. +func NewNodeManagerCaller(address common.Address, caller bind.ContractCaller) (*NodeManagerCaller, error) { + contract, err := bindNodeManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NodeManagerCaller{contract: contract}, nil +} + +// NewNodeManagerTransactor creates a new write-only instance of NodeManager, bound to a specific deployed contract. +func NewNodeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NodeManagerTransactor, error) { + contract, err := bindNodeManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NodeManagerTransactor{contract: contract}, nil +} + +// NewNodeManagerFilterer creates a new log filterer instance of NodeManager, bound to a specific deployed contract. +func NewNodeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NodeManagerFilterer, error) { + contract, err := bindNodeManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NodeManagerFilterer{contract: contract}, nil +} + +// bindNodeManager binds a generic wrapper to an already deployed contract. +func bindNodeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(NodeManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NodeManager *NodeManagerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _NodeManager.Contract.NodeManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NodeManager *NodeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NodeManager.Contract.NodeManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NodeManager *NodeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NodeManager.Contract.NodeManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NodeManager *NodeManagerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _NodeManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NodeManager *NodeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NodeManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NodeManager *NodeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NodeManager.Contract.contract.Transact(opts, method, params...) +} + +// GetNodeDetails is a free data retrieval call binding the contract method 0x3f0e0e47. +// +// Solidity: function getNodeDetails(enodeId string) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerCaller) GetNodeDetails(opts *bind.CallOpts, enodeId string) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + ret := new(struct { + OrgId string + EnodeId string + NodeStatus *big.Int + }) + out := ret + err := _NodeManager.contract.Call(opts, out, "getNodeDetails", enodeId) + return *ret, err +} + +// GetNodeDetails is a free data retrieval call binding the contract method 0x3f0e0e47. +// +// Solidity: function getNodeDetails(enodeId string) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerSession) GetNodeDetails(enodeId string) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + return _NodeManager.Contract.GetNodeDetails(&_NodeManager.CallOpts, enodeId) +} + +// GetNodeDetails is a free data retrieval call binding the contract method 0x3f0e0e47. +// +// Solidity: function getNodeDetails(enodeId string) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerCallerSession) GetNodeDetails(enodeId string) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + return _NodeManager.Contract.GetNodeDetails(&_NodeManager.CallOpts, enodeId) +} + +// GetNodeDetailsFromIndex is a free data retrieval call binding the contract method 0x97c07a9b. +// +// Solidity: function getNodeDetailsFromIndex(_nodeIndex uint256) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerCaller) GetNodeDetailsFromIndex(opts *bind.CallOpts, _nodeIndex *big.Int) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + ret := new(struct { + OrgId string + EnodeId string + NodeStatus *big.Int + }) + out := ret + err := _NodeManager.contract.Call(opts, out, "getNodeDetailsFromIndex", _nodeIndex) + return *ret, err +} + +// GetNodeDetailsFromIndex is a free data retrieval call binding the contract method 0x97c07a9b. +// +// Solidity: function getNodeDetailsFromIndex(_nodeIndex uint256) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerSession) GetNodeDetailsFromIndex(_nodeIndex *big.Int) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + return _NodeManager.Contract.GetNodeDetailsFromIndex(&_NodeManager.CallOpts, _nodeIndex) +} + +// GetNodeDetailsFromIndex is a free data retrieval call binding the contract method 0x97c07a9b. +// +// Solidity: function getNodeDetailsFromIndex(_nodeIndex uint256) constant returns(_orgId string, _enodeId string, _nodeStatus uint256) +func (_NodeManager *NodeManagerCallerSession) GetNodeDetailsFromIndex(_nodeIndex *big.Int) (struct { + OrgId string + EnodeId string + NodeStatus *big.Int +}, error) { + return _NodeManager.Contract.GetNodeDetailsFromIndex(&_NodeManager.CallOpts, _nodeIndex) +} + +// GetNumberOfNodes is a free data retrieval call binding the contract method 0xb81c806a. +// +// Solidity: function getNumberOfNodes() constant returns(uint256) +func (_NodeManager *NodeManagerCaller) GetNumberOfNodes(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _NodeManager.contract.Call(opts, out, "getNumberOfNodes") + return *ret0, err +} + +// GetNumberOfNodes is a free data retrieval call binding the contract method 0xb81c806a. +// +// Solidity: function getNumberOfNodes() constant returns(uint256) +func (_NodeManager *NodeManagerSession) GetNumberOfNodes() (*big.Int, error) { + return _NodeManager.Contract.GetNumberOfNodes(&_NodeManager.CallOpts) +} + +// GetNumberOfNodes is a free data retrieval call binding the contract method 0xb81c806a. +// +// Solidity: function getNumberOfNodes() constant returns(uint256) +func (_NodeManager *NodeManagerCallerSession) GetNumberOfNodes() (*big.Int, error) { + return _NodeManager.Contract.GetNumberOfNodes(&_NodeManager.CallOpts) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0xe3b09d84. +// +// Solidity: function addAdminNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactor) AddAdminNode(opts *bind.TransactOpts, _enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.contract.Transact(opts, "addAdminNode", _enodeId, _orgId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0xe3b09d84. +// +// Solidity: function addAdminNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerSession) AddAdminNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddAdminNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0xe3b09d84. +// +// Solidity: function addAdminNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactorSession) AddAdminNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddAdminNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactor) AddNode(opts *bind.TransactOpts, _enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.contract.Transact(opts, "addNode", _enodeId, _orgId) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerSession) AddNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactorSession) AddNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// AddOrgNode is a paid mutator transaction binding the contract method 0x3f5e1a45. +// +// Solidity: function addOrgNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactor) AddOrgNode(opts *bind.TransactOpts, _enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.contract.Transact(opts, "addOrgNode", _enodeId, _orgId) +} + +// AddOrgNode is a paid mutator transaction binding the contract method 0x3f5e1a45. +// +// Solidity: function addOrgNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerSession) AddOrgNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddOrgNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// AddOrgNode is a paid mutator transaction binding the contract method 0x3f5e1a45. +// +// Solidity: function addOrgNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactorSession) AddOrgNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.AddOrgNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// ApproveNode is a paid mutator transaction binding the contract method 0x86bc3652. +// +// Solidity: function approveNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactor) ApproveNode(opts *bind.TransactOpts, _enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.contract.Transact(opts, "approveNode", _enodeId, _orgId) +} + +// ApproveNode is a paid mutator transaction binding the contract method 0x86bc3652. +// +// Solidity: function approveNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerSession) ApproveNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.ApproveNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// ApproveNode is a paid mutator transaction binding the contract method 0x86bc3652. +// +// Solidity: function approveNode(_enodeId string, _orgId string) returns() +func (_NodeManager *NodeManagerTransactorSession) ApproveNode(_enodeId string, _orgId string) (*types.Transaction, error) { + return _NodeManager.Contract.ApproveNode(&_NodeManager.TransactOpts, _enodeId, _orgId) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_enodeId string, _orgId string, _action uint256) returns() +func (_NodeManager *NodeManagerTransactor) UpdateNodeStatus(opts *bind.TransactOpts, _enodeId string, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _NodeManager.contract.Transact(opts, "updateNodeStatus", _enodeId, _orgId, _action) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_enodeId string, _orgId string, _action uint256) returns() +func (_NodeManager *NodeManagerSession) UpdateNodeStatus(_enodeId string, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _NodeManager.Contract.UpdateNodeStatus(&_NodeManager.TransactOpts, _enodeId, _orgId, _action) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_enodeId string, _orgId string, _action uint256) returns() +func (_NodeManager *NodeManagerTransactorSession) UpdateNodeStatus(_enodeId string, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _NodeManager.Contract.UpdateNodeStatus(&_NodeManager.TransactOpts, _enodeId, _orgId, _action) +} + +// NodeManagerNodeActivatedIterator is returned from FilterNodeActivated and is used to iterate over the raw logs and unpacked data for NodeActivated events raised by the NodeManager contract. +type NodeManagerNodeActivatedIterator struct { + Event *NodeManagerNodeActivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeActivatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeActivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeActivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeActivated represents a NodeActivated event raised by the NodeManager contract. +type NodeManagerNodeActivated struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeActivated is a free log retrieval operation binding the contract event 0x49796be3ca168a59c8ae46c75a36a9bb3a84753d3e12a812f93ae010e783b14f. +// +// Solidity: e NodeActivated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeActivated(opts *bind.FilterOpts) (*NodeManagerNodeActivatedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeActivated") + if err != nil { + return nil, err + } + return &NodeManagerNodeActivatedIterator{contract: _NodeManager.contract, event: "NodeActivated", logs: logs, sub: sub}, nil +} + +// WatchNodeActivated is a free log subscription operation binding the contract event 0x49796be3ca168a59c8ae46c75a36a9bb3a84753d3e12a812f93ae010e783b14f. +// +// Solidity: e NodeActivated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeActivated(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeActivated) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeActivated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeActivated) + if err := _NodeManager.contract.UnpackLog(event, "NodeActivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeApprovedIterator is returned from FilterNodeApproved and is used to iterate over the raw logs and unpacked data for NodeApproved events raised by the NodeManager contract. +type NodeManagerNodeApprovedIterator struct { + Event *NodeManagerNodeApproved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeApprovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeApprovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeApproved represents a NodeApproved event raised by the NodeManager contract. +type NodeManagerNodeApproved struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeApproved is a free log retrieval operation binding the contract event 0x0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d. +// +// Solidity: e NodeApproved(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeApproved(opts *bind.FilterOpts) (*NodeManagerNodeApprovedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeApproved") + if err != nil { + return nil, err + } + return &NodeManagerNodeApprovedIterator{contract: _NodeManager.contract, event: "NodeApproved", logs: logs, sub: sub}, nil +} + +// WatchNodeApproved is a free log subscription operation binding the contract event 0x0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d. +// +// Solidity: e NodeApproved(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeApproved(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeApproved) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeApproved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeApproved) + if err := _NodeManager.contract.UnpackLog(event, "NodeApproved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeBlacklistedIterator is returned from FilterNodeBlacklisted and is used to iterate over the raw logs and unpacked data for NodeBlacklisted events raised by the NodeManager contract. +type NodeManagerNodeBlacklistedIterator struct { + Event *NodeManagerNodeBlacklisted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeBlacklistedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeBlacklisted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeBlacklisted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeBlacklistedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeBlacklistedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeBlacklisted represents a NodeBlacklisted event raised by the NodeManager contract. +type NodeManagerNodeBlacklisted struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeBlacklisted is a free log retrieval operation binding the contract event 0x4714623279994517c446c8fb72c3fdaca26434da1e2490d3976fe0cd880cfa7a. +// +// Solidity: e NodeBlacklisted(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeBlacklisted(opts *bind.FilterOpts) (*NodeManagerNodeBlacklistedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeBlacklisted") + if err != nil { + return nil, err + } + return &NodeManagerNodeBlacklistedIterator{contract: _NodeManager.contract, event: "NodeBlacklisted", logs: logs, sub: sub}, nil +} + +// WatchNodeBlacklisted is a free log subscription operation binding the contract event 0x4714623279994517c446c8fb72c3fdaca26434da1e2490d3976fe0cd880cfa7a. +// +// Solidity: e NodeBlacklisted(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeBlacklisted(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeBlacklisted) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeBlacklisted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeBlacklisted) + if err := _NodeManager.contract.UnpackLog(event, "NodeBlacklisted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeDeactivatedIterator is returned from FilterNodeDeactivated and is used to iterate over the raw logs and unpacked data for NodeDeactivated events raised by the NodeManager contract. +type NodeManagerNodeDeactivatedIterator struct { + Event *NodeManagerNodeDeactivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeDeactivatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeDeactivated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeDeactivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeDeactivated represents a NodeDeactivated event raised by the NodeManager contract. +type NodeManagerNodeDeactivated struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeDeactivated is a free log retrieval operation binding the contract event 0xc6c3720fe673e87bb26e06be713d514278aa94c3939cfe7c64b9bea4d486824a. +// +// Solidity: e NodeDeactivated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeDeactivated(opts *bind.FilterOpts) (*NodeManagerNodeDeactivatedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeDeactivated") + if err != nil { + return nil, err + } + return &NodeManagerNodeDeactivatedIterator{contract: _NodeManager.contract, event: "NodeDeactivated", logs: logs, sub: sub}, nil +} + +// WatchNodeDeactivated is a free log subscription operation binding the contract event 0xc6c3720fe673e87bb26e06be713d514278aa94c3939cfe7c64b9bea4d486824a. +// +// Solidity: e NodeDeactivated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeDeactivated(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeDeactivated) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeDeactivated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeDeactivated) + if err := _NodeManager.contract.UnpackLog(event, "NodeDeactivated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeProposedIterator is returned from FilterNodeProposed and is used to iterate over the raw logs and unpacked data for NodeProposed events raised by the NodeManager contract. +type NodeManagerNodeProposedIterator struct { + Event *NodeManagerNodeProposed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeProposedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeProposed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeProposed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeProposedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeProposedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeProposed represents a NodeProposed event raised by the NodeManager contract. +type NodeManagerNodeProposed struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeProposed is a free log retrieval operation binding the contract event 0xb1a7eec7dd1a516c3132d6d1f770758b19aa34c3a07c138caf662688b7e3556f. +// +// Solidity: e NodeProposed(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeProposed(opts *bind.FilterOpts) (*NodeManagerNodeProposedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeProposed") + if err != nil { + return nil, err + } + return &NodeManagerNodeProposedIterator{contract: _NodeManager.contract, event: "NodeProposed", logs: logs, sub: sub}, nil +} + +// WatchNodeProposed is a free log subscription operation binding the contract event 0xb1a7eec7dd1a516c3132d6d1f770758b19aa34c3a07c138caf662688b7e3556f. +// +// Solidity: e NodeProposed(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeProposed(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeProposed) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeProposed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeProposed) + if err := _NodeManager.contract.UnpackLog(event, "NodeProposed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeRecoveryCompletedIterator is returned from FilterNodeRecoveryCompleted and is used to iterate over the raw logs and unpacked data for NodeRecoveryCompleted events raised by the NodeManager contract. +type NodeManagerNodeRecoveryCompletedIterator struct { + Event *NodeManagerNodeRecoveryCompleted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeRecoveryCompletedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeRecoveryCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeRecoveryCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeRecoveryCompletedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeRecoveryCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeRecoveryCompleted represents a NodeRecoveryCompleted event raised by the NodeManager contract. +type NodeManagerNodeRecoveryCompleted struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeRecoveryCompleted is a free log retrieval operation binding the contract event 0x787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac. +// +// Solidity: e NodeRecoveryCompleted(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeRecoveryCompleted(opts *bind.FilterOpts) (*NodeManagerNodeRecoveryCompletedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeRecoveryCompleted") + if err != nil { + return nil, err + } + return &NodeManagerNodeRecoveryCompletedIterator{contract: _NodeManager.contract, event: "NodeRecoveryCompleted", logs: logs, sub: sub}, nil +} + +// WatchNodeRecoveryCompleted is a free log subscription operation binding the contract event 0x787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac. +// +// Solidity: e NodeRecoveryCompleted(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeRecoveryCompleted(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeRecoveryCompleted) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeRecoveryCompleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeRecoveryCompleted) + if err := _NodeManager.contract.UnpackLog(event, "NodeRecoveryCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// NodeManagerNodeRecoveryInitiatedIterator is returned from FilterNodeRecoveryInitiated and is used to iterate over the raw logs and unpacked data for NodeRecoveryInitiated events raised by the NodeManager contract. +type NodeManagerNodeRecoveryInitiatedIterator struct { + Event *NodeManagerNodeRecoveryInitiated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NodeManagerNodeRecoveryInitiatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeRecoveryInitiated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NodeManagerNodeRecoveryInitiated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NodeManagerNodeRecoveryInitiatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NodeManagerNodeRecoveryInitiatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NodeManagerNodeRecoveryInitiated represents a NodeRecoveryInitiated event raised by the NodeManager contract. +type NodeManagerNodeRecoveryInitiated struct { + EnodeId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNodeRecoveryInitiated is a free log retrieval operation binding the contract event 0xfd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb. +// +// Solidity: e NodeRecoveryInitiated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) FilterNodeRecoveryInitiated(opts *bind.FilterOpts) (*NodeManagerNodeRecoveryInitiatedIterator, error) { + + logs, sub, err := _NodeManager.contract.FilterLogs(opts, "NodeRecoveryInitiated") + if err != nil { + return nil, err + } + return &NodeManagerNodeRecoveryInitiatedIterator{contract: _NodeManager.contract, event: "NodeRecoveryInitiated", logs: logs, sub: sub}, nil +} + +// WatchNodeRecoveryInitiated is a free log subscription operation binding the contract event 0xfd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb. +// +// Solidity: e NodeRecoveryInitiated(_enodeId string, _orgId string) +func (_NodeManager *NodeManagerFilterer) WatchNodeRecoveryInitiated(opts *bind.WatchOpts, sink chan<- *NodeManagerNodeRecoveryInitiated) (event.Subscription, error) { + + logs, sub, err := _NodeManager.contract.WatchLogs(opts, "NodeRecoveryInitiated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NodeManagerNodeRecoveryInitiated) + if err := _NodeManager.contract.UnpackLog(event, "NodeRecoveryInitiated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/bind/org.go b/permission/bind/org.go new file mode 100644 index 0000000000..c65e443562 --- /dev/null +++ b/permission/bind/org.go @@ -0,0 +1,983 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// OrgManagerABI is the input ABI used to generate the binding from. +const OrgManagerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateOrg\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"approveOrgStatusUpdate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"getUltimateParent\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_pOrgId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addSubOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"_getOrgIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgIndex\",\"type\":\"uint256\"}],\"name\":\"getOrgInfo\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfOrgs\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_orgStatus\",\"type\":\"uint256\"}],\"name\":\"checkOrgStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_breadth\",\"type\":\"uint256\"},{\"name\":\"_depth\",\"type\":\"uint256\"}],\"name\":\"setUpOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"approveOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"addOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"checkOrgExists\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_porgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ultParent\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_level\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_status\",\"type\":\"uint256\"}],\"name\":\"OrgApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_porgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ultParent\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_level\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_status\",\"type\":\"uint256\"}],\"name\":\"OrgPendingApproval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_porgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ultParent\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_level\",\"type\":\"uint256\"}],\"name\":\"OrgSuspended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_porgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_ultParent\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_level\",\"type\":\"uint256\"}],\"name\":\"OrgSuspensionRevoked\",\"type\":\"event\"}]" + +// OrgManagerBin is the compiled bytecode used for deploying new contracts. +const OrgManagerBin = `60806040526000600160146101000a81548160ff02191690831515021790555060046002556004600355600060065534801561003a57600080fd5b506040516020806140b48339810180604052602081101561005a57600080fd5b810190808051906020019092919050505080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613ff8806100bc6000396000f3fe608060405234801561001057600080fd5b50600436106100d1576000357c0100000000000000000000000000000000000000000000000000000000900480637755ebdd1161008e5780637755ebdd1461060c5780638c8642df1461062a5780639e58eb9f14610707578063e302831614610794578063f9953de51461080d578063ffe40d1d14610886576100d1565b80630cc27493146100d657806314f775f91461016d578063177c8d8a146101f05780631f953480146102e2578063320d2c39146103b05780635c4f32ee1461047f575b600080fd5b610157600480360360408110156100ec57600080fd5b810190808035906020019064010000000081111561010957600080fd5b82018360208201111561011b57600080fd5b8035906020019184600183028401116401000000008311171561013d57600080fd5b909192939192939080359060200190929190505050610959565b6040518082815260200191505060405180910390f35b6101ee6004803603604081101561018357600080fd5b81019080803590602001906401000000008111156101a057600080fd5b8201836020820111156101b257600080fd5b803590602001918460018302840111640100000000831117156101d457600080fd5b909192939192939080359060200190929190505050610e46565b005b6102676004803603602081101561020657600080fd5b810190808035906020019064010000000081111561022357600080fd5b82018360208201111561023557600080fd5b8035906020019184600183028401116401000000008311171561025757600080fd5b909192939192939050505061111f565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102a757808201518184015260208101905061028c565b50505050905090810190601f1680156102d45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ae600480360360408110156102f857600080fd5b810190808035906020019064010000000081111561031557600080fd5b82018360208201111561032757600080fd5b8035906020019184600183028401116401000000008311171561034957600080fd5b90919293919293908035906020019064010000000081111561036a57600080fd5b82018360208201111561037c57600080fd5b8035906020019184600183028401116401000000008311171561039e57600080fd5b909192939192939050505061138f565b005b610469600480360360208110156103c657600080fd5b81019080803590602001906401000000008111156103e357600080fd5b8201836020820111156103f557600080fd5b8035906020019184600183028401116401000000008311171561041757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611672565b6040518082815260200191505060405180910390f35b6104ab6004803603602081101561049557600080fd5b8101908080359060200190929190505050611705565b60405180806020018060200180602001868152602001858152602001848103845289818151815260200191508051906020019080838360005b838110156104ff5780820151818401526020810190506104e4565b50505050905090810190601f16801561052c5780820380516001836020036101000a031916815260200191505b50848103835288818151815260200191508051906020019080838360005b8381101561056557808201518184015260208101905061054a565b50505050905090810190601f1680156105925780820380516001836020036101000a031916815260200191505b50848103825287818151815260200191508051906020019080838360005b838110156105cb5780820151818401526020810190506105b0565b50505050905090810190601f1680156105f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b610614611996565b6040518082815260200191505060405180910390f35b6106ed6004803603604081101561064057600080fd5b810190808035906020019064010000000081111561065d57600080fd5b82018360208201111561066f57600080fd5b8035906020019184600183028401116401000000008311171561069157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506119a3565b604051808215151515815260200191505060405180910390f35b6107926004803603606081101561071d57600080fd5b810190808035906020019064010000000081111561073a57600080fd5b82018360208201111561074c57600080fd5b8035906020019184600183028401116401000000008311171561076e57600080fd5b90919293919293908035906020019092919080359060200190929190505050611a70565b005b61080b600480360360208110156107aa57600080fd5b81019080803590602001906401000000008111156107c757600080fd5b8201836020820111156107d957600080fd5b803590602001918460018302840111640100000000831117156107fb57600080fd5b9091929391929390505050611c47565b005b6108846004803603602081101561082357600080fd5b810190808035906020019064010000000081111561084057600080fd5b82018360208201111561085257600080fd5b8035906020019184600183028401116401000000008311171561087457600080fd5b9091929391929390505050612149565b005b61093f6004803603602081101561089c57600080fd5b81019080803590602001906401000000008111156108b957600080fd5b8201836020820111156108cb57600080fd5b803590602001918460018302840111640100000000831117156108ed57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506123d9565b604051808215151515815260200191505060405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d6020811015610a0957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515610b0e826123d9565b1515141515610b85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b6001831480610b945750600283145b1515610beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180613f266025913960400191505060405180910390fd5b6000610c3a86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b90506001600482815481101515610c4d57fe5b906000526020600020906008020160060154141515610cb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180613f4b6027913960400191505060405180910390fd5b6000806001861415610cd0576002915060029050610ce3565b6002861415610ce25760049150600390505b5b60011515610d3589898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846119a3565b1515141515610d8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180613f726027913960400191505060405180910390fd5b6001861415610dea57610de588888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061246c565b610e38565b610e3788888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612767565b5b809450505050509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610eca57600080fd5b505afa158015610ede573d6000803e3d6000fd5b505050506040513d6020811015610ef457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515610ff9826123d9565b1515141515611070576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b60018214156110cb576110c684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612a7f565b611119565b61111884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d8d565b5b50505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611282576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60046112d184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b8154811015156112dd57fe5b90600052602060002090600802016004018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113825780601f1061135757610100808354040283529160200191611382565b820191906000526020600020905b81548152906001019060200180831161136557829003601f168201915b5050505050905092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561141357600080fd5b505afa158015611427573d6000803e3d6000fd5b505050506040513d602081101561143d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156114f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b838383836040516020018085858082843780830192505050807f2e00000000000000000000000000000000000000000000000000000000000000815250600101838380828437808301925050509450505050506040516020818303038152906040526000151561155f826123d9565b15151415156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f7267206578697374730000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61166b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060028061309c565b5050505050565b6000600160056000846040516020018082805190602001908083835b6020831015156116b3578051825260208201915060208101905060208303925061168e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b606080606060008060048681548110151561171c57fe5b906000526020600020906008020160000160048781548110151561173c57fe5b906000526020600020906008020160020160048881548110151561175c57fe5b906000526020600020906008020160040160048981548110151561177c57fe5b90600052602060002090600802016006015460048a81548110151561179d57fe5b906000526020600020906008020160010154848054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118445780601f1061181957610100808354040283529160200191611844565b820191906000526020600020905b81548152906001019060200180831161182757829003601f168201915b50505050509450838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118e05780601f106118b5576101008083540402835291602001916118e0565b820191906000526020600020905b8154815290600101906020018083116118c357829003601f168201915b50505050509350828054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561197c5780601f106119515761010080835404028352916020019161197c565b820191906000526020600020905b81548152906001019060200180831161195f57829003601f168201915b505050505092509450945094509450945091939590929450565b6000600480549050905090565b6000806119af84611672565b9050600060056000866040516020018082805190602001908083835b6020831015156119f057805182526020820191506020810190506020830392506119cb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081526020019081526020016000205414158015611a67575082600482815481101515611a5357fe5b906000526020600020906008020160010154145b91505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611af457600080fd5b505afa158015611b08573d6000803e3d6000fd5b505050506040513d6020811015611b1e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611c33602060405190810160405280600081525085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001600261309c565b806002819055508160038190555050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611ccb57600080fd5b505afa158015611cdf573d6000803e3d6000fd5b505050506040513d6020811015611cf557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60011515611dfb83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060016119a3565b1515141515611e72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000611ec183838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b90506002600482815481101515611ed457fe5b9060005260206000209060080201600101819055507fd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c600482815481101515611f1957fe5b9060005260206000209060080201600001600483815481101515611f3957fe5b9060005260206000209060080201600201600484815481101515611f5957fe5b9060005260206000209060080201600401600485815481101515611f7957fe5b90600052602060002090600802016006015460026040518080602001806020018060200186815260200185815260200184810384528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561202a5780601f10611fff5761010080835404028352916020019161202a565b820191906000526020600020905b81548152906001019060200180831161200d57829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156120ad5780601f10612082576101008083540402835291602001916120ad565b820191906000526020600020905b81548152906001019060200180831161209057829003601f168201915b50508481038252878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121305780601f1061210557610100808354040283529160200191612130565b820191906000526020600020905b81548152906001019060200180831161211357829003601f168201915b50509850505050505050505060405180910390a1505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156121cd57600080fd5b505afa1580156121e1573d6000803e3d6000fd5b505050506040513d60208110156121f757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b81818080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600015156122fc826123d9565b1515141515612373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f7267206578697374730000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6123d4602060405190810160405280600081525084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060018061309c565b505050565b60008060056000846040516020018082805190602001908083835b60208310151561241957805182526020820191506020810190506020830392506123f4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081526020019081526020016000205414159050919050565b6001151561247b8260026119a3565b15151415156124d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180613f996034913960400191505060405180910390fd5b60006124e082611672565b905060036004828154811015156124f357fe5b9060005260206000209060080201600101819055507f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561253857fe5b906000526020600020906008020160000160048381548110151561255857fe5b906000526020600020906008020160020160048481548110151561257857fe5b906000526020600020906008020160040160048581548110151561259857fe5b9060005260206000209060080201600601546003604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156126495780601f1061261e57610100808354040283529160200191612649565b820191906000526020600020905b81548152906001019060200180831161262c57829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156126cc5780601f106126a1576101008083540402835291602001916126cc565b820191906000526020600020905b8154815290600101906020018083116126af57829003601f168201915b505084810382528781815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561274f5780601f106127245761010080835404028352916020019161274f565b820191906000526020600020905b81548152906001019060200180831161273257829003601f168201915b50509850505050505050505060405180910390a15050565b600115156127768260046119a3565b15151415156127ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e2073757370656e64656420737461746500000000000081525060200191505060405180910390fd5b60006127f882611672565b9050600560048281548110151561280b57fe5b9060005260206000209060080201600101819055507f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561285057fe5b906000526020600020906008020160000160048381548110151561287057fe5b906000526020600020906008020160020160048481548110151561289057fe5b90600052602060002090600802016004016004858154811015156128b057fe5b9060005260206000209060080201600601546005604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156129615780601f1061293657610100808354040283529160200191612961565b820191906000526020600020905b81548152906001019060200180831161294457829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156129e45780601f106129b9576101008083540402835291602001916129e4565b820191906000526020600020905b8154815290600101906020018083116129c757829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612a675780601f10612a3c57610100808354040283529160200191612a67565b820191906000526020600020905b815481529060010190602001808311612a4a57829003601f168201915b50509850505050505050505060405180910390a15050565b60011515612a8e8260036119a3565b1515141515612b05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000612b1082611672565b905060048082815481101515612b2257fe5b9060005260206000209060080201600101819055507f73ccf8d6c8385bf5347269bd59712da33183c1a5e1702494bcdb87d0f4674d96600482815481101515612b6757fe5b9060005260206000209060080201600001600483815481101515612b8757fe5b9060005260206000209060080201600201600484815481101515612ba757fe5b9060005260206000209060080201600401600485815481101515612bc757fe5b90600052602060002090600802016006015460405180806020018060200180602001858152602001848103845288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612c705780601f10612c4557610100808354040283529160200191612c70565b820191906000526020600020905b815481529060010190602001808311612c5357829003601f168201915b5050848103835287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612cf35780601f10612cc857610100808354040283529160200191612cf3565b820191906000526020600020905b815481529060010190602001808311612cd657829003601f168201915b5050848103825286818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612d765780601f10612d4b57610100808354040283529160200191612d76565b820191906000526020600020905b815481529060010190602001808311612d5957829003601f168201915b505097505050505050505060405180910390a15050565b60011515612d9c8260056119a3565b1515141515612e13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000612e1e82611672565b90506002600482815481101515612e3157fe5b9060005260206000209060080201600101819055507f882f030c609566cd82918a97d457fd48f9cfcefd11282e2654cde3f94579c15f600482815481101515612e7657fe5b9060005260206000209060080201600001600483815481101515612e9657fe5b9060005260206000209060080201600201600484815481101515612eb657fe5b9060005260206000209060080201600401600485815481101515612ed657fe5b90600052602060002090600802016006015460405180806020018060200180602001858152602001848103845288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612f7f5780601f10612f5457610100808354040283529160200191612f7f565b820191906000526020600020905b815481529060010190602001808311612f6257829003601f168201915b50508481038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130025780601f10612fd757610100808354040283529160200191613002565b820191906000526020600020905b815481529060010190602001808311612fe557829003601f168201915b50508481038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130855780601f1061305a57610100808354040283529160200191613085565b820191906000526020600020905b81548152906001019060200180831161306857829003601f168201915b505097505050505050505060405180910390a15050565b600080905060008090506000809050600185141561312f57856040516020018082805190602001908083835b6020831015156130ed57805182526020820191506020810190506020830392506130c8565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001209150613299565b866040516020018082805190602001908083835b6020831015156131685780518252602082019150602081019050602083039250613143565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120925086866040516020018083805190602001908083835b6020831015156131df57805182526020820191506020810190506020830392506131ba565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e0000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b60208310151561325a5780518252602082019150602081019050602083039250613235565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040528051906020012091505b60066000815480929190600101919050555060065460056000848152602001908152602001600020819055506000600480548091906001016132db9190613cab565b905060018614156133a057856004828154811015156132f657fe5b906000526020600020906008020160060181905550600060048281548110151561331c57fe5b9060005260206000209060080201600501819055508660048281548110151561334157fe5b90600052602060002090600802016003019080519060200190613365929190613cdd565b508660048281548110151561337657fe5b9060005260206000209060080201600401908051906020019061339a929190613cdd565b5061374d565b600160056000868152602001908152602001600020540391506003546004838154811015156133cb57fe5b906000526020600020906008020160070180549050101515613455576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f62726561647468206c6576656c2065786365656465640000000000000000000081525060200191505060405180910390fd5b60025460048381548110151561346757fe5b9060005260206000209060080201600601541015156134ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6465707468206c6576656c20657863656564656400000000000000000000000081525060200191505060405180910390fd5b60016004838154811015156134ff57fe5b9060005260206000209060080201600601540160048281548110151561352157fe5b9060005260206000209060080201600601819055508160048281548110151561354657fe5b90600052602060002090600802016005018190555060048281548110151561356a57fe5b906000526020600020906008020160040160048281548110151561358a57fe5b906000526020600020906008020160040190805460018160011615610100020316600290046135ba929190613d5d565b5060006004838154811015156135cc57fe5b906000526020600020906008020160070180548091906001016135ef9190613de4565b90508160048481548110151561360157fe5b90600052602060002090600802016007018281548110151561361f57fe5b906000526020600020018190555088886040516020018083805190602001908083835b6020831015156136675780518252602082019150602081019050602083039250613642565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e0000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b6020831015156136e257805182526020820191506020810190506020830392506136bd565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405260048381548110151561372657fe5b9060005260206000209060080201600301908051906020019061374a929190613cdd565b50505b8660048281548110151561375d57fe5b90600052602060002090600802016000019080519060200190613781929190613cdd565b508760048281548110151561379257fe5b906000526020600020906008020160020190805190602001906137b6929190613cdd565b50846004828154811015156137c757fe5b9060005260206000209060080201600101819055506001851415613a45577f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561381557fe5b906000526020600020906008020160000160048381548110151561383557fe5b906000526020600020906008020160020160048481548110151561385557fe5b906000526020600020906008020160040160048581548110151561387557fe5b9060005260206000209060080201600601546001604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139265780601f106138fb57610100808354040283529160200191613926565b820191906000526020600020905b81548152906001019060200180831161390957829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139a95780601f1061397e576101008083540402835291602001916139a9565b820191906000526020600020905b81548152906001019060200180831161398c57829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613a2c5780601f10613a0157610100808354040283529160200191613a2c565b820191906000526020600020905b815481529060010190602001808311613a0f57829003601f168201915b50509850505050505050505060405180910390a1613ca1565b7fd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c600482815481101515613a7557fe5b9060005260206000209060080201600001600483815481101515613a9557fe5b9060005260206000209060080201600201600484815481101515613ab557fe5b9060005260206000209060080201600401600485815481101515613ad557fe5b906000526020600020906008020160060154600260405180806020018060200180602001868152602001858152602001848103845289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613b865780601f10613b5b57610100808354040283529160200191613b86565b820191906000526020600020905b815481529060010190602001808311613b6957829003601f168201915b5050848103835288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613c095780601f10613bde57610100808354040283529160200191613c09565b820191906000526020600020905b815481529060010190602001808311613bec57829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613c8c5780601f10613c6157610100808354040283529160200191613c8c565b820191906000526020600020905b815481529060010190602001808311613c6f57829003601f168201915b50509850505050505050505060405180910390a15b5050505050505050565b815481835581811115613cd857600802816008028360005260206000209182019101613cd79190613e10565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d1e57805160ff1916838001178555613d4c565b82800160010185558215613d4c579182015b82811115613d4b578251825591602001919060010190613d30565b5b509050613d599190613e97565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d965780548555613dd3565b82800160010185558215613dd357600052602060002091601f016020900482015b82811115613dd2578254825591600101919060010190613db7565b5b509050613de09190613e97565b5090565b815481835581811115613e0b57818360005260206000209182019101613e0a9190613e97565b5b505050565b613e9491905b80821115613e905760008082016000613e2f9190613ebc565b6001820160009055600282016000613e479190613ebc565b600382016000613e579190613ebc565b600482016000613e679190613ebc565b60058201600090556006820160009055600782016000613e879190613f04565b50600801613e16565b5090565b90565b613eb991905b80821115613eb5576000816000905550600101613e9d565b5090565b90565b50805460018160011615610100020316600290046000825580601f10613ee25750613f01565b601f016020900490600052602060002090810190613f009190613e97565b5b50565b5080546000825590600052602060002090810190613f229190613e97565b5056fe696e76616c696420616374696f6e2e206f7065726174696f6e206e6f7420616c6c6f7765646e6f742061206d6173746572206f72672e206f7065726174696f6e206e6f7420616c6c6f7765646f72672073746174757320646f6573206e6f7420616c6c6f7720746865206f7065726174696f6e6f7267206e6f7420696e20617070726f766564207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e65a165627a7a72305820ad4f7ede501fde744bd99a211aae38fa1573644d4dc550d1c4e668f404270efd0029` + +// DeployOrgManager deploys a new Ethereum contract, binding an instance of OrgManager to it. +func DeployOrgManager(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address) (common.Address, *types.Transaction, *OrgManager, error) { + parsed, err := abi.JSON(strings.NewReader(OrgManagerABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(OrgManagerBin), backend, _permUpgradable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OrgManager{OrgManagerCaller: OrgManagerCaller{contract: contract}, OrgManagerTransactor: OrgManagerTransactor{contract: contract}, OrgManagerFilterer: OrgManagerFilterer{contract: contract}}, nil +} + +// OrgManager is an auto generated Go binding around an Ethereum contract. +type OrgManager struct { + OrgManagerCaller // Read-only binding to the contract + OrgManagerTransactor // Write-only binding to the contract + OrgManagerFilterer // Log filterer for contract events +} + +// OrgManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type OrgManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OrgManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OrgManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OrgManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OrgManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OrgManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OrgManagerSession struct { + Contract *OrgManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OrgManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OrgManagerCallerSession struct { + Contract *OrgManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// OrgManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OrgManagerTransactorSession struct { + Contract *OrgManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OrgManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type OrgManagerRaw struct { + Contract *OrgManager // Generic contract binding to access the raw methods on +} + +// OrgManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OrgManagerCallerRaw struct { + Contract *OrgManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// OrgManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OrgManagerTransactorRaw struct { + Contract *OrgManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewOrgManager creates a new instance of OrgManager, bound to a specific deployed contract. +func NewOrgManager(address common.Address, backend bind.ContractBackend) (*OrgManager, error) { + contract, err := bindOrgManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OrgManager{OrgManagerCaller: OrgManagerCaller{contract: contract}, OrgManagerTransactor: OrgManagerTransactor{contract: contract}, OrgManagerFilterer: OrgManagerFilterer{contract: contract}}, nil +} + +// NewOrgManagerCaller creates a new read-only instance of OrgManager, bound to a specific deployed contract. +func NewOrgManagerCaller(address common.Address, caller bind.ContractCaller) (*OrgManagerCaller, error) { + contract, err := bindOrgManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OrgManagerCaller{contract: contract}, nil +} + +// NewOrgManagerTransactor creates a new write-only instance of OrgManager, bound to a specific deployed contract. +func NewOrgManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*OrgManagerTransactor, error) { + contract, err := bindOrgManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OrgManagerTransactor{contract: contract}, nil +} + +// NewOrgManagerFilterer creates a new log filterer instance of OrgManager, bound to a specific deployed contract. +func NewOrgManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*OrgManagerFilterer, error) { + contract, err := bindOrgManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OrgManagerFilterer{contract: contract}, nil +} + +// bindOrgManager binds a generic wrapper to an already deployed contract. +func bindOrgManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OrgManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OrgManager *OrgManagerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _OrgManager.Contract.OrgManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OrgManager *OrgManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OrgManager.Contract.OrgManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OrgManager *OrgManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OrgManager.Contract.OrgManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OrgManager *OrgManagerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _OrgManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OrgManager *OrgManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OrgManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OrgManager *OrgManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OrgManager.Contract.contract.Transact(opts, method, params...) +} + +// GetOrgIndex is a free data retrieval call binding the contract method 0x320d2c39. +// +// Solidity: function _getOrgIndex(_orgId string) constant returns(uint256) +func (_OrgManager *OrgManagerCaller) GetOrgIndex(opts *bind.CallOpts, _orgId string) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _OrgManager.contract.Call(opts, out, "_getOrgIndex", _orgId) + return *ret0, err +} + +// GetOrgIndex is a free data retrieval call binding the contract method 0x320d2c39. +// +// Solidity: function _getOrgIndex(_orgId string) constant returns(uint256) +func (_OrgManager *OrgManagerSession) GetOrgIndex(_orgId string) (*big.Int, error) { + return _OrgManager.Contract.GetOrgIndex(&_OrgManager.CallOpts, _orgId) +} + +// GetOrgIndex is a free data retrieval call binding the contract method 0x320d2c39. +// +// Solidity: function _getOrgIndex(_orgId string) constant returns(uint256) +func (_OrgManager *OrgManagerCallerSession) GetOrgIndex(_orgId string) (*big.Int, error) { + return _OrgManager.Contract.GetOrgIndex(&_OrgManager.CallOpts, _orgId) +} + +// CheckOrgExists is a free data retrieval call binding the contract method 0xffe40d1d. +// +// Solidity: function checkOrgExists(_orgId string) constant returns(bool) +func (_OrgManager *OrgManagerCaller) CheckOrgExists(opts *bind.CallOpts, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _OrgManager.contract.Call(opts, out, "checkOrgExists", _orgId) + return *ret0, err +} + +// CheckOrgExists is a free data retrieval call binding the contract method 0xffe40d1d. +// +// Solidity: function checkOrgExists(_orgId string) constant returns(bool) +func (_OrgManager *OrgManagerSession) CheckOrgExists(_orgId string) (bool, error) { + return _OrgManager.Contract.CheckOrgExists(&_OrgManager.CallOpts, _orgId) +} + +// CheckOrgExists is a free data retrieval call binding the contract method 0xffe40d1d. +// +// Solidity: function checkOrgExists(_orgId string) constant returns(bool) +func (_OrgManager *OrgManagerCallerSession) CheckOrgExists(_orgId string) (bool, error) { + return _OrgManager.Contract.CheckOrgExists(&_OrgManager.CallOpts, _orgId) +} + +// CheckOrgStatus is a free data retrieval call binding the contract method 0x8c8642df. +// +// Solidity: function checkOrgStatus(_orgId string, _orgStatus uint256) constant returns(bool) +func (_OrgManager *OrgManagerCaller) CheckOrgStatus(opts *bind.CallOpts, _orgId string, _orgStatus *big.Int) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _OrgManager.contract.Call(opts, out, "checkOrgStatus", _orgId, _orgStatus) + return *ret0, err +} + +// CheckOrgStatus is a free data retrieval call binding the contract method 0x8c8642df. +// +// Solidity: function checkOrgStatus(_orgId string, _orgStatus uint256) constant returns(bool) +func (_OrgManager *OrgManagerSession) CheckOrgStatus(_orgId string, _orgStatus *big.Int) (bool, error) { + return _OrgManager.Contract.CheckOrgStatus(&_OrgManager.CallOpts, _orgId, _orgStatus) +} + +// CheckOrgStatus is a free data retrieval call binding the contract method 0x8c8642df. +// +// Solidity: function checkOrgStatus(_orgId string, _orgStatus uint256) constant returns(bool) +func (_OrgManager *OrgManagerCallerSession) CheckOrgStatus(_orgId string, _orgStatus *big.Int) (bool, error) { + return _OrgManager.Contract.CheckOrgStatus(&_OrgManager.CallOpts, _orgId, _orgStatus) +} + +// GetNumberOfOrgs is a free data retrieval call binding the contract method 0x7755ebdd. +// +// Solidity: function getNumberOfOrgs() constant returns(uint256) +func (_OrgManager *OrgManagerCaller) GetNumberOfOrgs(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _OrgManager.contract.Call(opts, out, "getNumberOfOrgs") + return *ret0, err +} + +// GetNumberOfOrgs is a free data retrieval call binding the contract method 0x7755ebdd. +// +// Solidity: function getNumberOfOrgs() constant returns(uint256) +func (_OrgManager *OrgManagerSession) GetNumberOfOrgs() (*big.Int, error) { + return _OrgManager.Contract.GetNumberOfOrgs(&_OrgManager.CallOpts) +} + +// GetNumberOfOrgs is a free data retrieval call binding the contract method 0x7755ebdd. +// +// Solidity: function getNumberOfOrgs() constant returns(uint256) +func (_OrgManager *OrgManagerCallerSession) GetNumberOfOrgs() (*big.Int, error) { + return _OrgManager.Contract.GetNumberOfOrgs(&_OrgManager.CallOpts) +} + +// GetOrgInfo is a free data retrieval call binding the contract method 0x5c4f32ee. +// +// Solidity: function getOrgInfo(_orgIndex uint256) constant returns(string, string, string, uint256, uint256) +func (_OrgManager *OrgManagerCaller) GetOrgInfo(opts *bind.CallOpts, _orgIndex *big.Int) (string, string, string, *big.Int, *big.Int, error) { + var ( + ret0 = new(string) + ret1 = new(string) + ret2 = new(string) + ret3 = new(*big.Int) + ret4 = new(*big.Int) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + ret4, + } + err := _OrgManager.contract.Call(opts, out, "getOrgInfo", _orgIndex) + return *ret0, *ret1, *ret2, *ret3, *ret4, err +} + +// GetOrgInfo is a free data retrieval call binding the contract method 0x5c4f32ee. +// +// Solidity: function getOrgInfo(_orgIndex uint256) constant returns(string, string, string, uint256, uint256) +func (_OrgManager *OrgManagerSession) GetOrgInfo(_orgIndex *big.Int) (string, string, string, *big.Int, *big.Int, error) { + return _OrgManager.Contract.GetOrgInfo(&_OrgManager.CallOpts, _orgIndex) +} + +// GetOrgInfo is a free data retrieval call binding the contract method 0x5c4f32ee. +// +// Solidity: function getOrgInfo(_orgIndex uint256) constant returns(string, string, string, uint256, uint256) +func (_OrgManager *OrgManagerCallerSession) GetOrgInfo(_orgIndex *big.Int) (string, string, string, *big.Int, *big.Int, error) { + return _OrgManager.Contract.GetOrgInfo(&_OrgManager.CallOpts, _orgIndex) +} + +// GetUltimateParent is a free data retrieval call binding the contract method 0x177c8d8a. +// +// Solidity: function getUltimateParent(_orgId string) constant returns(string) +func (_OrgManager *OrgManagerCaller) GetUltimateParent(opts *bind.CallOpts, _orgId string) (string, error) { + var ( + ret0 = new(string) + ) + out := ret0 + err := _OrgManager.contract.Call(opts, out, "getUltimateParent", _orgId) + return *ret0, err +} + +// GetUltimateParent is a free data retrieval call binding the contract method 0x177c8d8a. +// +// Solidity: function getUltimateParent(_orgId string) constant returns(string) +func (_OrgManager *OrgManagerSession) GetUltimateParent(_orgId string) (string, error) { + return _OrgManager.Contract.GetUltimateParent(&_OrgManager.CallOpts, _orgId) +} + +// GetUltimateParent is a free data retrieval call binding the contract method 0x177c8d8a. +// +// Solidity: function getUltimateParent(_orgId string) constant returns(string) +func (_OrgManager *OrgManagerCallerSession) GetUltimateParent(_orgId string) (string, error) { + return _OrgManager.Contract.GetUltimateParent(&_OrgManager.CallOpts, _orgId) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf9953de5. +// +// Solidity: function addOrg(_orgId string) returns() +func (_OrgManager *OrgManagerTransactor) AddOrg(opts *bind.TransactOpts, _orgId string) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "addOrg", _orgId) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf9953de5. +// +// Solidity: function addOrg(_orgId string) returns() +func (_OrgManager *OrgManagerSession) AddOrg(_orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.AddOrg(&_OrgManager.TransactOpts, _orgId) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf9953de5. +// +// Solidity: function addOrg(_orgId string) returns() +func (_OrgManager *OrgManagerTransactorSession) AddOrg(_orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.AddOrg(&_OrgManager.TransactOpts, _orgId) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x1f953480. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string) returns() +func (_OrgManager *OrgManagerTransactor) AddSubOrg(opts *bind.TransactOpts, _pOrgId string, _orgId string) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "addSubOrg", _pOrgId, _orgId) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x1f953480. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string) returns() +func (_OrgManager *OrgManagerSession) AddSubOrg(_pOrgId string, _orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.AddSubOrg(&_OrgManager.TransactOpts, _pOrgId, _orgId) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x1f953480. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string) returns() +func (_OrgManager *OrgManagerTransactorSession) AddSubOrg(_pOrgId string, _orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.AddSubOrg(&_OrgManager.TransactOpts, _pOrgId, _orgId) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0xe3028316. +// +// Solidity: function approveOrg(_orgId string) returns() +func (_OrgManager *OrgManagerTransactor) ApproveOrg(opts *bind.TransactOpts, _orgId string) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "approveOrg", _orgId) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0xe3028316. +// +// Solidity: function approveOrg(_orgId string) returns() +func (_OrgManager *OrgManagerSession) ApproveOrg(_orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.ApproveOrg(&_OrgManager.TransactOpts, _orgId) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0xe3028316. +// +// Solidity: function approveOrg(_orgId string) returns() +func (_OrgManager *OrgManagerTransactorSession) ApproveOrg(_orgId string) (*types.Transaction, error) { + return _OrgManager.Contract.ApproveOrg(&_OrgManager.TransactOpts, _orgId) +} + +// ApproveOrgStatusUpdate is a paid mutator transaction binding the contract method 0x14f775f9. +// +// Solidity: function approveOrgStatusUpdate(_orgId string, _action uint256) returns() +func (_OrgManager *OrgManagerTransactor) ApproveOrgStatusUpdate(opts *bind.TransactOpts, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "approveOrgStatusUpdate", _orgId, _action) +} + +// ApproveOrgStatusUpdate is a paid mutator transaction binding the contract method 0x14f775f9. +// +// Solidity: function approveOrgStatusUpdate(_orgId string, _action uint256) returns() +func (_OrgManager *OrgManagerSession) ApproveOrgStatusUpdate(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.ApproveOrgStatusUpdate(&_OrgManager.TransactOpts, _orgId, _action) +} + +// ApproveOrgStatusUpdate is a paid mutator transaction binding the contract method 0x14f775f9. +// +// Solidity: function approveOrgStatusUpdate(_orgId string, _action uint256) returns() +func (_OrgManager *OrgManagerTransactorSession) ApproveOrgStatusUpdate(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.ApproveOrgStatusUpdate(&_OrgManager.TransactOpts, _orgId, _action) +} + +// SetUpOrg is a paid mutator transaction binding the contract method 0x9e58eb9f. +// +// Solidity: function setUpOrg(_orgId string, _breadth uint256, _depth uint256) returns() +func (_OrgManager *OrgManagerTransactor) SetUpOrg(opts *bind.TransactOpts, _orgId string, _breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "setUpOrg", _orgId, _breadth, _depth) +} + +// SetUpOrg is a paid mutator transaction binding the contract method 0x9e58eb9f. +// +// Solidity: function setUpOrg(_orgId string, _breadth uint256, _depth uint256) returns() +func (_OrgManager *OrgManagerSession) SetUpOrg(_orgId string, _breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.SetUpOrg(&_OrgManager.TransactOpts, _orgId, _breadth, _depth) +} + +// SetUpOrg is a paid mutator transaction binding the contract method 0x9e58eb9f. +// +// Solidity: function setUpOrg(_orgId string, _breadth uint256, _depth uint256) returns() +func (_OrgManager *OrgManagerTransactorSession) SetUpOrg(_orgId string, _breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.SetUpOrg(&_OrgManager.TransactOpts, _orgId, _breadth, _depth) +} + +// UpdateOrg is a paid mutator transaction binding the contract method 0x0cc27493. +// +// Solidity: function updateOrg(_orgId string, _action uint256) returns(uint256) +func (_OrgManager *OrgManagerTransactor) UpdateOrg(opts *bind.TransactOpts, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.contract.Transact(opts, "updateOrg", _orgId, _action) +} + +// UpdateOrg is a paid mutator transaction binding the contract method 0x0cc27493. +// +// Solidity: function updateOrg(_orgId string, _action uint256) returns(uint256) +func (_OrgManager *OrgManagerSession) UpdateOrg(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.UpdateOrg(&_OrgManager.TransactOpts, _orgId, _action) +} + +// UpdateOrg is a paid mutator transaction binding the contract method 0x0cc27493. +// +// Solidity: function updateOrg(_orgId string, _action uint256) returns(uint256) +func (_OrgManager *OrgManagerTransactorSession) UpdateOrg(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _OrgManager.Contract.UpdateOrg(&_OrgManager.TransactOpts, _orgId, _action) +} + +// OrgManagerOrgApprovedIterator is returned from FilterOrgApproved and is used to iterate over the raw logs and unpacked data for OrgApproved events raised by the OrgManager contract. +type OrgManagerOrgApprovedIterator struct { + Event *OrgManagerOrgApproved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OrgManagerOrgApprovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OrgManagerOrgApprovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OrgManagerOrgApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OrgManagerOrgApproved represents a OrgApproved event raised by the OrgManager contract. +type OrgManagerOrgApproved struct { + OrgId string + PorgId string + UltParent string + Level *big.Int + Status *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOrgApproved is a free log retrieval operation binding the contract event 0xd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c. +// +// Solidity: e OrgApproved(_orgId string, _porgId string, _ultParent string, _level uint256, _status uint256) +func (_OrgManager *OrgManagerFilterer) FilterOrgApproved(opts *bind.FilterOpts) (*OrgManagerOrgApprovedIterator, error) { + + logs, sub, err := _OrgManager.contract.FilterLogs(opts, "OrgApproved") + if err != nil { + return nil, err + } + return &OrgManagerOrgApprovedIterator{contract: _OrgManager.contract, event: "OrgApproved", logs: logs, sub: sub}, nil +} + +// WatchOrgApproved is a free log subscription operation binding the contract event 0xd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c. +// +// Solidity: e OrgApproved(_orgId string, _porgId string, _ultParent string, _level uint256, _status uint256) +func (_OrgManager *OrgManagerFilterer) WatchOrgApproved(opts *bind.WatchOpts, sink chan<- *OrgManagerOrgApproved) (event.Subscription, error) { + + logs, sub, err := _OrgManager.contract.WatchLogs(opts, "OrgApproved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OrgManagerOrgApproved) + if err := _OrgManager.contract.UnpackLog(event, "OrgApproved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// OrgManagerOrgPendingApprovalIterator is returned from FilterOrgPendingApproval and is used to iterate over the raw logs and unpacked data for OrgPendingApproval events raised by the OrgManager contract. +type OrgManagerOrgPendingApprovalIterator struct { + Event *OrgManagerOrgPendingApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OrgManagerOrgPendingApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgPendingApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgPendingApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OrgManagerOrgPendingApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OrgManagerOrgPendingApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OrgManagerOrgPendingApproval represents a OrgPendingApproval event raised by the OrgManager contract. +type OrgManagerOrgPendingApproval struct { + OrgId string + PorgId string + UltParent string + Level *big.Int + Status *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOrgPendingApproval is a free log retrieval operation binding the contract event 0x0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b. +// +// Solidity: e OrgPendingApproval(_orgId string, _porgId string, _ultParent string, _level uint256, _status uint256) +func (_OrgManager *OrgManagerFilterer) FilterOrgPendingApproval(opts *bind.FilterOpts) (*OrgManagerOrgPendingApprovalIterator, error) { + + logs, sub, err := _OrgManager.contract.FilterLogs(opts, "OrgPendingApproval") + if err != nil { + return nil, err + } + return &OrgManagerOrgPendingApprovalIterator{contract: _OrgManager.contract, event: "OrgPendingApproval", logs: logs, sub: sub}, nil +} + +// WatchOrgPendingApproval is a free log subscription operation binding the contract event 0x0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b. +// +// Solidity: e OrgPendingApproval(_orgId string, _porgId string, _ultParent string, _level uint256, _status uint256) +func (_OrgManager *OrgManagerFilterer) WatchOrgPendingApproval(opts *bind.WatchOpts, sink chan<- *OrgManagerOrgPendingApproval) (event.Subscription, error) { + + logs, sub, err := _OrgManager.contract.WatchLogs(opts, "OrgPendingApproval") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OrgManagerOrgPendingApproval) + if err := _OrgManager.contract.UnpackLog(event, "OrgPendingApproval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// OrgManagerOrgSuspendedIterator is returned from FilterOrgSuspended and is used to iterate over the raw logs and unpacked data for OrgSuspended events raised by the OrgManager contract. +type OrgManagerOrgSuspendedIterator struct { + Event *OrgManagerOrgSuspended // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OrgManagerOrgSuspendedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgSuspended) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgSuspended) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OrgManagerOrgSuspendedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OrgManagerOrgSuspendedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OrgManagerOrgSuspended represents a OrgSuspended event raised by the OrgManager contract. +type OrgManagerOrgSuspended struct { + OrgId string + PorgId string + UltParent string + Level *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOrgSuspended is a free log retrieval operation binding the contract event 0x73ccf8d6c8385bf5347269bd59712da33183c1a5e1702494bcdb87d0f4674d96. +// +// Solidity: e OrgSuspended(_orgId string, _porgId string, _ultParent string, _level uint256) +func (_OrgManager *OrgManagerFilterer) FilterOrgSuspended(opts *bind.FilterOpts) (*OrgManagerOrgSuspendedIterator, error) { + + logs, sub, err := _OrgManager.contract.FilterLogs(opts, "OrgSuspended") + if err != nil { + return nil, err + } + return &OrgManagerOrgSuspendedIterator{contract: _OrgManager.contract, event: "OrgSuspended", logs: logs, sub: sub}, nil +} + +// WatchOrgSuspended is a free log subscription operation binding the contract event 0x73ccf8d6c8385bf5347269bd59712da33183c1a5e1702494bcdb87d0f4674d96. +// +// Solidity: e OrgSuspended(_orgId string, _porgId string, _ultParent string, _level uint256) +func (_OrgManager *OrgManagerFilterer) WatchOrgSuspended(opts *bind.WatchOpts, sink chan<- *OrgManagerOrgSuspended) (event.Subscription, error) { + + logs, sub, err := _OrgManager.contract.WatchLogs(opts, "OrgSuspended") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OrgManagerOrgSuspended) + if err := _OrgManager.contract.UnpackLog(event, "OrgSuspended", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// OrgManagerOrgSuspensionRevokedIterator is returned from FilterOrgSuspensionRevoked and is used to iterate over the raw logs and unpacked data for OrgSuspensionRevoked events raised by the OrgManager contract. +type OrgManagerOrgSuspensionRevokedIterator struct { + Event *OrgManagerOrgSuspensionRevoked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OrgManagerOrgSuspensionRevokedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgSuspensionRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OrgManagerOrgSuspensionRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OrgManagerOrgSuspensionRevokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OrgManagerOrgSuspensionRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OrgManagerOrgSuspensionRevoked represents a OrgSuspensionRevoked event raised by the OrgManager contract. +type OrgManagerOrgSuspensionRevoked struct { + OrgId string + PorgId string + UltParent string + Level *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOrgSuspensionRevoked is a free log retrieval operation binding the contract event 0x882f030c609566cd82918a97d457fd48f9cfcefd11282e2654cde3f94579c15f. +// +// Solidity: e OrgSuspensionRevoked(_orgId string, _porgId string, _ultParent string, _level uint256) +func (_OrgManager *OrgManagerFilterer) FilterOrgSuspensionRevoked(opts *bind.FilterOpts) (*OrgManagerOrgSuspensionRevokedIterator, error) { + + logs, sub, err := _OrgManager.contract.FilterLogs(opts, "OrgSuspensionRevoked") + if err != nil { + return nil, err + } + return &OrgManagerOrgSuspensionRevokedIterator{contract: _OrgManager.contract, event: "OrgSuspensionRevoked", logs: logs, sub: sub}, nil +} + +// WatchOrgSuspensionRevoked is a free log subscription operation binding the contract event 0x882f030c609566cd82918a97d457fd48f9cfcefd11282e2654cde3f94579c15f. +// +// Solidity: e OrgSuspensionRevoked(_orgId string, _porgId string, _ultParent string, _level uint256) +func (_OrgManager *OrgManagerFilterer) WatchOrgSuspensionRevoked(opts *bind.WatchOpts, sink chan<- *OrgManagerOrgSuspensionRevoked) (event.Subscription, error) { + + logs, sub, err := _OrgManager.contract.WatchLogs(opts, "OrgSuspensionRevoked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OrgManagerOrgSuspensionRevoked) + if err := _OrgManager.contract.UnpackLog(event, "OrgSuspensionRevoked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/bind/permission_impl.go b/permission/bind/permission_impl.go new file mode 100644 index 0000000000..d83e1524bc --- /dev/null +++ b/permission/bind/permission_impl.go @@ -0,0 +1,966 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// PermImplABI is the input ABI used to generate the binding from. +const PermImplABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_action\",\"type\":\"uint256\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"updateAccountStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_access\",\"type\":\"uint256\"},{\"name\":\"_voter\",\"type\":\"bool\"},{\"name\":\"_admin\",\"type\":\"bool\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"addNewRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nwAdminOrg\",\"type\":\"string\"},{\"name\":\"_nwAdminRole\",\"type\":\"string\"},{\"name\":\"_oAdminRole\",\"type\":\"string\"}],\"name\":\"setPolicy\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"startBlacklistedAccountRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"approveOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"updateOrgStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"addAdminNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"assignAdminRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"updateNetworkBootStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"approveBlacklistedAccountRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNetworkBootStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"addAdminAccount\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"addNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"removeRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"approveBlacklistedNodeRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"validateAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"approveAdminRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"assignAccountRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"isOrgAdmin\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_breadth\",\"type\":\"uint256\"},{\"name\":\"_depth\",\"type\":\"uint256\"}],\"name\":\"init\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_pOrgId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"addSubOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"approveOrgStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"startBlacklistedNodeRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPolicyDetails\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isNetworkAdmin\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"updateNodeStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"getPendingOp\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nwAdminOrg\",\"type\":\"string\"},{\"name\":\"_nwAdminRole\",\"type\":\"string\"},{\"name\":\"_oAdminRole\",\"type\":\"string\"},{\"name\":\"_networkBootStatus\",\"type\":\"bool\"}],\"name\":\"setMigrationPolicy\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_caller\",\"type\":\"address\"}],\"name\":\"addOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"},{\"name\":\"_orgManager\",\"type\":\"address\"},{\"name\":\"_rolesManager\",\"type\":\"address\"},{\"name\":\"_accountManager\",\"type\":\"address\"},{\"name\":\"_voterManager\",\"type\":\"address\"},{\"name\":\"_nodeManager\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_networkBootStatus\",\"type\":\"bool\"}],\"name\":\"PermissionsInitialized\",\"type\":\"event\"}]" + +// PermImplBin is the compiled bytecode used for deploying new contracts. +const PermImplBin = `608060405260036009556000600a60006101000a81548160ff0219169083151502179055503480156200003157600080fd5b5060405160c0806200a14c833981018060405260c08110156200005357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505085600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505050619f1b80620002316000396000f3fe608060405234801561001057600080fd5b50600436106101ec576000357c010000000000000000000000000000000000000000000000000000000090048063655a8ef511610121578063b5546564116100bf578063dbfad7111161008e578063dbfad711146115e2578063f346a3a7146116da578063f5ad584a14611872578063f922f802146119a1576101ec565b8063b55465641461128f578063c3dc8e0914611332578063cc9ba6fa14611420578063d1aa0c2014611586576101ec565b80638baa8191116100fb5780638baa819114610e8f5780639bd3810114611021578063a5843f0814611114578063a64d28601461114c576101ec565b8063655a8ef514610bf55780636b568d7614610ce35780638884304114610dd6576101ec565b8063404bf3eb1161018e5780634cbfa82e116101685780634cbfa82e146109b35780634fe57e7a146109d557806359a260a314610a195780635ca5adbe14610b07576101ec565b8063404bf3eb146107ca57806344478e79146108d85780634b20f45f146108fa576101ec565b80631c249912116101ca5780631c249912146104e75780633bc07dea146105a05780633cf5f33b146106ae5780633f25c28814610751576101ec565b806304e81f1e146101f15780631b04c276146102b45780631b610220146103c4575b600080fd5b6102b26004803603608081101561020757600080fd5b810190808035906020019064010000000081111561022457600080fd5b82018360208201111561023657600080fd5b8035906020019184600183028401116401000000008311171561025857600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611aaf565b005b6103c2600480360360c08110156102ca57600080fd5b81019080803590602001906401000000008111156102e757600080fd5b8201836020820111156102f957600080fd5b8035906020019184600183028401116401000000008311171561031b57600080fd5b90919293919293908035906020019064010000000081111561033c57600080fd5b82018360208201111561034e57600080fd5b8035906020019184600183028401116401000000008311171561037057600080fd5b909192939192939080359060200190929190803515159060200190929190803515159060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e2b565b005b6104e5600480360360608110156103da57600080fd5b81019080803590602001906401000000008111156103f757600080fd5b82018360208201111561040957600080fd5b8035906020019184600183028401116401000000008311171561042b57600080fd5b90919293919293908035906020019064010000000081111561044c57600080fd5b82018360208201111561045e57600080fd5b8035906020019184600183028401116401000000008311171561048057600080fd5b9091929391929390803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b909192939192939050505061221c565b005b61059e600480360360608110156104fd57600080fd5b810190808035906020019064010000000081111561051a57600080fd5b82018360208201111561052c57600080fd5b8035906020019184600183028401116401000000008311171561054e57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061242b565b005b6106ac600480360360808110156105b657600080fd5b81019080803590602001906401000000008111156105d357600080fd5b8201836020820111156105e557600080fd5b8035906020019184600183028401116401000000008311171561060757600080fd5b90919293919293908035906020019064010000000081111561062857600080fd5b82018360208201111561063a57600080fd5b8035906020019184600183028401116401000000008311171561065c57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128a0565b005b61074f600480360360608110156106c457600080fd5b81019080803590602001906401000000008111156106e157600080fd5b8201836020820111156106f357600080fd5b8035906020019184600183028401116401000000008311171561071557600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613058565b005b6107c86004803603602081101561076757600080fd5b810190808035906020019064010000000081111561078457600080fd5b82018360208201111561079657600080fd5b803590602001918460018302840111640100000000831117156107b857600080fd5b90919293919293905050506134c1565b005b6108d6600480360360808110156107e057600080fd5b81019080803590602001906401000000008111156107fd57600080fd5b82018360208201111561080f57600080fd5b8035906020019184600183028401116401000000008311171561083157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561087257600080fd5b82018360208201111561088457600080fd5b803590602001918460018302840111640100000000831117156108a657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506137f6565b005b6108e0613d6b565b604051808215151515815260200191505060405180910390f35b6109b16004803603606081101561091057600080fd5b810190808035906020019064010000000081111561092d57600080fd5b82018360208201111561093f57600080fd5b8035906020019184600183028401116401000000008311171561096157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6e565b005b6109bb6142de565b604051808215151515815260200191505060405180910390f35b610a17600480360360208110156109eb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142f5565b005b610b0560048036036060811015610a2f57600080fd5b8101908080359060200190640100000000811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b80359060200191846001830284011164010000000083111715610a8057600080fd5b909192939192939080359060200190640100000000811115610aa157600080fd5b820183602082011115610ab357600080fd5b80359060200191846001830284011164010000000083111715610ad557600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614762565b005b610bf360048036036060811015610b1d57600080fd5b8101908080359060200190640100000000811115610b3a57600080fd5b820183602082011115610b4c57600080fd5b80359060200191846001830284011164010000000083111715610b6e57600080fd5b909192939192939080359060200190640100000000811115610b8f57600080fd5b820183602082011115610ba157600080fd5b80359060200191846001830284011164010000000083111715610bc357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614b30565b005b610ce160048036036060811015610c0b57600080fd5b8101908080359060200190640100000000811115610c2857600080fd5b820183602082011115610c3a57600080fd5b80359060200191846001830284011164010000000083111715610c5c57600080fd5b909192939192939080359060200190640100000000811115610c7d57600080fd5b820183602082011115610c8f57600080fd5b80359060200191846001830284011164010000000083111715610cb157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615178565b005b610dbc60048036036040811015610cf957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610d3657600080fd5b820183602082011115610d4857600080fd5b80359060200191846001830284011164010000000083111715610d6a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506154ea565b604051808215151515815260200191505060405180910390f35b610e8d60048036036060811015610dec57600080fd5b8101908080359060200190640100000000811115610e0957600080fd5b820183602082011115610e1b57600080fd5b80359060200191846001830284011164010000000083111715610e3d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615656565b005b61101f60048036036080811015610ea557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ee257600080fd5b820183602082011115610ef457600080fd5b80359060200191846001830284011164010000000083111715610f1657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610f7957600080fd5b820183602082011115610f8b57600080fd5b80359060200191846001830284011164010000000083111715610fad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615c48565b005b6110fa6004803603604081101561103757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561107457600080fd5b82018360208201111561108657600080fd5b803590602001918460018302840111640100000000831117156110a857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061635e565b604051808215151515815260200191505060405180910390f35b61114a6004803603604081101561112a57600080fd5b8101908080359060200190929190803590602001909291905050506168a9565b005b61128d6004803603608081101561116257600080fd5b810190808035906020019064010000000081111561117f57600080fd5b82018360208201111561119157600080fd5b803590602001918460018302840111640100000000831117156111b357600080fd5b9091929391929390803590602001906401000000008111156111d457600080fd5b8201836020820111156111e657600080fd5b8035906020019184600183028401116401000000008311171561120857600080fd5b90919293919293908035906020019064010000000081111561122957600080fd5b82018360208201111561123b57600080fd5b8035906020019184600183028401116401000000008311171561125d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616f4a565b005b611330600480360360608110156112a557600080fd5b81019080803590602001906401000000008111156112c257600080fd5b8201836020820111156112d457600080fd5b803590602001918460018302840111640100000000831117156112f657600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050617527565b005b61141e6004803603606081101561134857600080fd5b810190808035906020019064010000000081111561136557600080fd5b82018360208201111561137757600080fd5b8035906020019184600183028401116401000000008311171561139957600080fd5b9091929391929390803590602001906401000000008111156113ba57600080fd5b8201836020820111156113cc57600080fd5b803590602001918460018302840111640100000000831117156113ee57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506179dc565b005b611428617e74565b6040518080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561147a57808201518184015260208101905061145f565b50505050905090810190601f1680156114a75780820380516001836020036101000a031916815260200191505b50848103835287818151815260200191508051906020019080838360005b838110156114e05780820151818401526020810190506114c5565b50505050905090810190601f16801561150d5780820380516001836020036101000a031916815260200191505b50848103825286818151815260200191508051906020019080838360005b8381101561154657808201518184015260208101905061152b565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b6115c86004803603602081101561159c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050618073565b604051808215151515815260200191505060405180910390f35b6116d8600480360360808110156115f857600080fd5b810190808035906020019064010000000081111561161557600080fd5b82018360208201111561162757600080fd5b8035906020019184600183028401116401000000008311171561164957600080fd5b90919293919293908035906020019064010000000081111561166a57600080fd5b82018360208201111561167c57600080fd5b8035906020019184600183028401116401000000008311171561169e57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506182fd565b005b611751600480360360208110156116f057600080fd5b810190808035906020019064010000000081111561170d57600080fd5b82018360208201111561171f57600080fd5b8035906020019184600183028401116401000000008311171561174157600080fd5b909192939192939050505061867b565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156117cd5780820151818401526020810190506117b2565b50505050905090810190601f1680156117fa5780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b83811015611833578082015181840152602081019050611818565b50505050905090810190601f1680156118605780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b61199f6004803603608081101561188857600080fd5b81019080803590602001906401000000008111156118a557600080fd5b8201836020820111156118b757600080fd5b803590602001918460018302840111640100000000831117156118d957600080fd5b9091929391929390803590602001906401000000008111156118fa57600080fd5b82018360208201111561190c57600080fd5b8035906020019184600183028401116401000000008311171561192e57600080fd5b90919293919293908035906020019064010000000081111561194f57600080fd5b82018360208201111561196157600080fd5b8035906020019184600183028401116401000000008311171561198357600080fd5b9091929391929390803515159060200190929190505050618844565b005b611aad600480360360808110156119b757600080fd5b81019080803590602001906401000000008111156119d457600080fd5b8201836020820111156119e657600080fd5b80359060200191846001830284011164010000000083111715611a0857600080fd5b909192939192939080359060200190640100000000811115611a2957600080fd5b820183602082011115611a3b57600080fd5b80359060200191846001830284011164010000000083111715611a5d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506189ef565b005b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611b3357600080fd5b505afa158015611b47573d6000803e3d6000fd5b505050506040513d6020811015611b5d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515611c47838361635e565b1515141515611ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b6001841480611cb05750600284145b80611cbb5750600384145b1515611d12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180619e5b6025913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a888888886040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b5050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611eaf57600080fd5b505afa158015611ec3573d6000803e3d6000fd5b505050506040513d6020811015611ed957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515611fc182619245565b1515141515612038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001151561208c838361635e565b15151415156120e6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b7135798c8c8c8c8c8c8c6040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001868152602001851515151581526020018415151515815260200183810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508381038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509950505050505050505050600060405180830381600087803b1580156121f757600080fd5b505af115801561220b573d6000803e3d6000fd5b505050505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156122a057600080fd5b505afa1580156122b4573d6000803e3d6000fd5b505050506040513d60208110156122ca57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612360576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff1615151415156123ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8686600691906123fd929190619db5565b5084846007919061240f929190619db5565b50828260089190612421929190619db5565b5050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156124af57600080fd5b505afa1580156124c3573d6000803e3d6000fd5b505050506040513d60208110156124d957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561256f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b806001151561257d82618073565b15151415156125d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a86868660046040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156126d057600080fd5b505af11580156126e4573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600687878760066040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156128215780601f106127f657610100808354040283529160200191612821565b820191906000526020600020905b81548152906001019060200180831161280457829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b15801561288157600080fd5b505af1158015612895573d6000803e3d6000fd5b505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561292457600080fd5b505afa158015612938573d6000803e3d6000fd5b505050506040513d602081101561294e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156129e4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156129f282618073565b1515141515612a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b60011515612a9f88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001619386565b1515141515612b16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b612bbc60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612baf5780601f10612b8457610100808354040283529160200191612baf565b820191906000526020600020905b815481529060010190602001808311612b9257829003601f168201915b50505050508360016194c7565b1561304f57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e302831688886040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015612c7e57600080fd5b505af1158015612c92573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b713579600889896009546001806040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018681526020018515151515815260200184151515158152602001838103835289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612db05780601f10612d8557610100808354040283529160200191612db0565b820191906000526020600020905b815481529060010190602001808311612d9357829003601f168201915b50508381038252888882818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612e0157600080fd5b505af1158015612e15573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386bc365286868a8a6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c214e5e58888866040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b15801561301257600080fd5b505af1158015613026573d6000803e3d6000fd5b505050506040513d602081101561303c57600080fd5b8101908080519060200190929190505050505b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156130dc57600080fd5b505afa1580156130f0573d6000803e3d6000fd5b505050506040513d602081101561310657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561319c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156131aa82618073565b1515141515613204576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc274938787876040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b1580156132cb57600080fd5b505af11580156132df573d6000803e3d6000fd5b505050506040513d60208110156132f557600080fd5b81019080805190602001909291905050509050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600688886000866040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156134415780601f1061341657610100808354040283529160200191613441565b820191906000526020600020905b81548152906001019060200180831161342457829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b1580156134a157600080fd5b505af11580156134b5573d6000803e3d6000fd5b50505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561354557600080fd5b505afa158015613559573d6000803e3d6000fd5b505050506040513d602081101561356f57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613605576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515613691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3b09d84848460066040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352868682818152602001925080828437600081840152601f19601f8201169050808301925050508381038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156137b65780601f1061378b576101008083540402835291602001916137b6565b820191906000526020600020905b81548152906001019060200180831161379957829003601f168201915b505095505050505050600060405180830381600087803b1580156137d957600080fd5b505af11580156137ed573d6000803e3d6000fd5b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561387a57600080fd5b505afa15801561388e573d6000803e3d6000fd5b505050506040513d60208110156138a457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561393a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001151561398c8261963f565b1515141515613a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b8160011515613a1182618073565b1515141515613a6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d878a8a898960016040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015613b9857600080fd5b505af1158015613bac573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d60068a8a8a60046040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848103845289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613ce95780601f10613cbe57610100808354040283529160200191613ce9565b820191906000526020600020905b815481529060010190602001808311613ccc57829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b158015613d4957600080fd5b505af1158015613d5d573d6000803e3d6000fd5b505050505050505050505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613df157600080fd5b505afa158015613e05573d6000803e3d6000fd5b505050506040513d6020811015613e1b57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613eb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515613f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b6001600a60006101000a81548160ff021916908315150217905550600a60009054906101000a900460ff1691505090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613ff257600080fd5b505afa158015614006573d6000803e3d6000fd5b505050506040513d602081101561401c57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156140b2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156140c082618073565b151514151561411a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6141c060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156141b35780601f10614188576101008083540402835291602001916141b3565b820191906000526020600020905b81548152906001019060200180831161419657829003601f168201915b50505050508360066194c7565b156142d7576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a86868660056040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156142be57600080fd5b505af11580156142d2573d6000803e3d6000fd5b505050505b5050505050565b6000600a60009054906101000a900460ff16905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561437957600080fd5b505afa15801561438d573d6000803e3d6000fd5b505050506040513d60208110156143a357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515614439576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff1615151415156144c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b61456b60068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561455e5780601f106145335761010080835404028352916020019161455e565b820191906000526020600020905b81548152906001019060200180831161454157829003601f168201915b5050505050836001619777565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d836006600760026040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184815260200183810383528681815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561469f5780601f106146745761010080835404028352916020019161469f565b820191906000526020600020905b81548152906001019060200180831161468257829003601f168201915b50508381038252858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156147225780601f106146f757610100808354040283529160200191614722565b820191906000526020600020905b81548152906001019060200180831161470557829003601f168201915b50509650505050505050600060405180830381600087803b15801561474657600080fd5b505af115801561475a573d6000803e3d6000fd5b505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156147e657600080fd5b505afa1580156147fa573d6000803e3d6000fd5b505050506040513d602081101561481057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156148a6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156148f882619245565b151514151561496f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156149c3838361635e565b1515141515614a1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f5e1a4587878b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015614b0e57600080fd5b505af1158015614b22573d6000803e3d6000fd5b505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015614bb457600080fd5b505afa158015614bc8573d6000803e3d6000fd5b505050506040513d6020811015614bde57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515614c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515614cc682619245565b1515141515614d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515614d91838361635e565b1515141515614deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b60076040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015614e795780601f10614e4e57610100808354040283529160200191614e79565b820191906000526020600020905b815481529060010190602001808311614e5c57829003601f168201915b50509250505060405160208183030381529060405280519060200120888860405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014158015614ff1575060086040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015614f7f5780601f10614f5457610100808354040283529160200191614f7f565b820191906000526020600020905b815481529060010190602001808311614f6257829003601f168201915b50509250505060405160208183030381529060405280519060200120888860405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014155b1515615065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f61646d696e20726f6c65732063616e6e6f742062652072656d6f76656400000081525060200191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6343012898989896040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b15801561515657600080fd5b505af115801561516a573d6000803e3d6000fd5b505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156151fc57600080fd5b505afa158015615210573d6000803e3d6000fd5b505050506040513d602081101561522657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156152bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156152ca82618073565b1515141515615324576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6153ca60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156153bd5780601f10615392576101008083540402835291602001916153bd565b820191906000526020600020905b8154815290600101906020018083116153a057829003601f168201915b50505050508360056194c7565b156154e257600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc501468585898960056040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156154c957600080fd5b505af11580156154dd573d6000803e3d6000fd5b505050505b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b568d7684846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156155c85780820151818401526020810190506155ad565b50505050905090810190601f1680156155f55780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561561357600080fd5b505afa158015615627573d6000803e3d6000fd5b505050506040513d602081101561563d57600080fd5b8101908080519060200190929190505050905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156156da57600080fd5b505afa1580156156ee573d6000803e3d6000fd5b505050506040513d602081101561570457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561579a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156157a882618073565b1515141515615802576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6158a860068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561589b5780601f106158705761010080835404028352916020019161589b565b820191906000526020600020905b81548152906001019060200180831161587e57829003601f168201915b50505050508360046194c7565b15615c41576000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631d09dc9388886040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040805180830381600087803b15801561596b57600080fd5b505af115801561597f573d6000803e3d6000fd5b505050506040513d604081101561599557600080fd5b810190808051906020019092919080519060200190929190505050915091508115615a6157615a6060068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015615a535780601f10615a2857610100808354040283529160200191615a53565b820191906000526020600020905b815481529060010190602001808311615a3657829003601f168201915b5050505050826000619777565b5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c214e5e58989896040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b158015615b5357600080fd5b505af1158015615b67573d6000803e3d6000fd5b505050506040513d6020811015615b7d57600080fd5b810190808051906020019092919050505090508015615c3d57615c3c60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015615c2f5780601f10615c0457610100808354040283529160200191615c2f565b820191906000526020600020905b815481529060010190602001808311615c1257829003601f168201915b5050505050876001619777565b5b5050505b5050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015615ccc57600080fd5b505afa158015615ce0573d6000803e3d6000fd5b505050506040513d6020811015615cf657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515615d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b808360011515615d9c838361635e565b1515141515615df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b8460011515615e0482619245565b1515141515615e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b60011515615e8988886154ea565b1515141515615f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60011515615f0e8688619a0c565b1515141515615f85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f726f6c6520646f6573206e6f742065786973747300000000000000000000000081525060200191505060405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663be322e548789615fd08b619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015616043578082015181840152602081019050616028565b50505050905090810190601f1680156160705780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156160a957808201518184015260208101905061608e565b50505050905090810190601f1680156160d65780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b8381101561610f5780820151818401526020810190506160f4565b50505050905090810190601f16801561613c5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b15801561615d57600080fd5b505afa158015616171573d6000803e3d6000fd5b505050506040513d602081101561618757600080fd5b810190808051906020019092919050505090506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663143a5604898989856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184151515158152602001838103835286818151815260200191508051906020019080838360005b8381101561628657808201518184015260208101905061626b565b50505050905090810190601f1680156162b35780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156162ec5780820151818401526020810190506162d1565b50505050905090810190601f1680156163195780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561633c57600080fd5b505af1158015616350573d6000803e3d6000fd5b505050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8b42bf484846163a886619c27565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561644957808201518184015260208101905061642e565b50505050905090810190601f1680156164765780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156164af578082015181840152602081019050616494565b50505050905090810190601f1680156164dc5780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038186803b1580156164fc57600080fd5b505afa158015616510573d6000803e3d6000fd5b505050506040513d602081101561652657600080fd5b81019080805190602001909291905050501561654557600190506168a3565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663be322e546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381d66b23866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060006040518083038186803b15801561663d57600080fd5b505afa158015616651573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561667b57600080fd5b81019080805164010000000081111561669357600080fd5b828101905060208101848111156166a957600080fd5b81518560018202830111640100000000821117156166c657600080fd5b5050929190505050846166d886619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561674b578082015181840152602081019050616730565b50505050905090810190601f1680156167785780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156167b1578082015181840152602081019050616796565b50505050905090810190601f1680156167de5780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156168175780820151818401526020810190506167fc565b50505050905090810190601f1680156168445780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b15801561686557600080fd5b505afa158015616879573d6000803e3d6000fd5b505050506040513d602081101561688f57600080fd5b810190808051906020019092919050505090505b92915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561692d57600080fd5b505afa158015616941573d6000803e3d6000fd5b505050506040513d602081101561695757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156169ed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515616a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639e58eb9f600685856040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001848152602001838152602001828103825285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616b7b5780601f10616b5057610100808354040283529160200191616b7b565b820191906000526020600020905b815481529060010190602001808311616b5e57829003601f168201915b5050945050505050600060405180830381600087803b158015616b9d57600080fd5b505af1158015616bb1573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b713579600760066009546001806040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018681526020018515151515815260200184151515158152602001838103835288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616ccf5780601f10616ca457610100808354040283529160200191616ccf565b820191906000526020600020905b815481529060010190602001808311616cb257829003601f168201915b5050838103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616d525780601f10616d2757610100808354040283529160200191616d52565b820191906000526020600020905b815481529060010190602001808311616d3557829003601f168201915b5050975050505050505050600060405180830381600087803b158015616d7757600080fd5b505af1158015616d8b573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cef7f6af600760086040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616e885780601f10616e5d57610100808354040283529160200191616e88565b820191906000526020600020905b815481529060010190602001808311616e6b57829003601f168201915b5050838103825284818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616f0b5780601f10616ee057610100808354040283529160200191616f0b565b820191906000526020600020905b815481529060010190602001808311616eee57829003601f168201915b5050945050505050600060405180830381600087803b158015616f2d57600080fd5b505af1158015616f41573d6000803e3d6000fd5b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015616fce57600080fd5b505afa158015616fe2573d6000803e3d6000fd5b505050506040513d6020811015616ff857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561708e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156170e08261963f565b1515141515617157576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b8188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156171ab838361635e565b1515141515617205576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f9534808b8b8b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156172f657600080fd5b505af115801561730a573d6000803e3d6000fd5b5050505060608a8a8a8a604051602001808060200180602001806020018481038452888882818152602001925080828437600081840152601f19601f820116905080830192505050848103835260018152602001807f2e000000000000000000000000000000000000000000000000000000000000008152506020018481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509750505050505050506040516020818303038152906040529050600087879050111561751a57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f5e1a458888846040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352868682818152602001925080828437600081840152601f19601f820116905080830192505050838103825284818151815260200191508051906020019080838360005b838110156174b2578082015181840152602081019050617497565b50505050905090810190601f1680156174df5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561750157600080fd5b505af1158015617515573d6000803e3d6000fd5b505050505b5050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156175ab57600080fd5b505afa1580156175bf573d6000803e3d6000fd5b505050506040513d60208110156175d557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561766b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b806001151561767982618073565b15151415156176d3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b60018314806176e25750600283145b1515617756576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4f7065726174696f6e206e6f7420616c6c6f776564000000000000000000000081525060200191505060405180910390fd5b600080600185141561776f576002915060039050617782565b60028514156177815760039150600590505b5b600115156177d488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505083619386565b151514151561784b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6f7065726174696f6e206e6f7420616c6c6f776564000000000000000000000081525060200191505060405180910390fd5b6178f060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156178e45780601f106178b9576101008083540402835291602001916178e4565b820191906000526020600020905b8154815290600101906020018083116178c757829003601f168201915b505050505085846194c7565b156179d357600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166314f775f98888886040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b1580156179ba57600080fd5b505af11580156179ce573d6000803e3d6000fd5b505050505b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015617a6057600080fd5b505afa158015617a74573d6000803e3d6000fd5b505050506040513d6020811015617a8a57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515617b20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8060011515617b2e82618073565b1515141515617b88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc501468585898960046040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b158015617c8257600080fd5b505af1158015617c96573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600688888888600060056040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184810384528b818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015617dd65780601f10617dab57610100808354040283529160200191617dd6565b820191906000526020600020905b815481529060010190602001808311617db957829003601f168201915b505084810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015617e5457600080fd5b505af1158015617e68573d6000803e3d6000fd5b50505050505050505050565b60608060606000600660076008600a60009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015617f265780601f10617efb57610100808354040283529160200191617f26565b820191906000526020600020905b815481529060010190602001808311617f0957829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015617fc25780601f10617f9757610100808354040283529160200191617fc2565b820191906000526020600020905b815481529060010190602001808311617fa557829003601f168201915b50505050509250818054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561805e5780601f106180335761010080835404028352916020019161805e565b820191906000526020600020905b81548152906001019060200180831161804157829003601f168201915b50505050509150935093509350935090919293565b6000600760405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156181035780601f106180d857610100808354040283529160200191618103565b820191906000526020600020905b8154815290600101906020018083116180e657829003601f168201915b505092505050604051602081830303815290604052805190602001206000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381d66b23846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060006040518083038186803b1580156181d957600080fd5b505afa1580156181ed573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561821757600080fd5b81019080805164010000000081111561822f57600080fd5b8281019050602081018481111561824557600080fd5b815185600182028301116401000000008211171561826257600080fd5b50509291905050506040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156182ad578082015181840152602081019050618292565b50505050905090810190601f1680156182da5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120149050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561838157600080fd5b505afa158015618395573d6000803e3d6000fd5b505050506040513d60208110156183ab57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618441576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515618495838361635e565b15151415156184ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b60018414806184fe5750600284145b806185095750600384145b1515618560576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180619e5b6025913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc5014687878b8b896040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b15801561865957600080fd5b505af115801561866d573d6000803e3d6000fd5b505050505050505050505050565b606080600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663014e6acc87876040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561873c57600080fd5b505afa158015618750573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561877a57600080fd5b81019080805164010000000081111561879257600080fd5b828101905060208101848111156187a857600080fd5b81518560018202830111640100000000821117156187c557600080fd5b505092919060200180516401000000008111156187e157600080fd5b828101905060208101848111156187f757600080fd5b815185600182028301116401000000008211171561881457600080fd5b50509291906020018051906020019092919080519060200190929190505050935093509350935092959194509250565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515618995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8787600691906189a6929190619db5565b508585600791906189b8929190619db5565b508383600891906189ca929190619db5565b5081600a60006101000a81548160ff0219169083151502179055505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015618a7357600080fd5b505afa158015618a87573d6000803e3d6000fd5b505050506040513d6020811015618a9d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618b33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6001801515600a60009054906101000a900460ff161515141515618bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8160011515618bcd82618073565b1515141515618c27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d60068a8a8a8a8a60016040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184810384528b818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015618d625780601f10618d3757610100808354040283529160200191618d62565b820191906000526020600020905b815481529060010190602001808311618d4557829003601f168201915b505084810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015618de057600080fd5b505af1158015618df4573d6000803e3d6000fd5b50505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f9953de589896040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015618eb557600080fd5b505af1158015618ec9573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a97a440687878b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015618fbe57600080fd5b505af1158015618fd2573d6000803e3d6000fd5b5050505060011515619028858a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506154ea565b151514151561909f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d858a8a600860016040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018481526020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156191fe5780601f106191d3576101008083540402835291602001916191fe565b820191906000526020600020905b8154815290600101906020018083116191e157829003601f168201915b5050975050505050505050600060405180830381600087803b15801561922357600080fd5b505af1158015619237573d6000803e3d6000fd5b505050505050505050505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c8642df8360026040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156192f95780820151818401526020810190506192de565b50505050905090810190601f1680156193265780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561934457600080fd5b505afa158015619358573d6000803e3d6000fd5b505050506040513d602081101561936e57600080fd5b81019080805190602001909291905050509050919050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c8642df84846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561943957808201518184015260208101905061941e565b50505050905090810190601f1680156194665780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561948457600080fd5b505afa158015619498573d6000803e3d6000fd5b505050506040513d60208110156194ae57600080fd5b8101908080519060200190929190505050905092915050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b02138648585856040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156195ad578082015181840152602081019050619592565b50505050905090810190601f1680156195da5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156195fb57600080fd5b505af115801561960f573d6000803e3d6000fd5b505050506040513d602081101561962557600080fd5b810190808051906020019092919050505090509392505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ffe40d1d836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156196eb5780820151818401526020810190506196d0565b50505050905090810190601f1680156197185780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561973557600080fd5b505afa158015619749573d6000803e3d6000fd5b505050506040513d602081101561975f57600080fd5b81019080805190602001909291905050509050919050565b80156198c457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635607395b84846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561985a57808201518184015260208101905061983f565b50505050905090810190601f1680156198875780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156198a757600080fd5b505af11580156198bb573d6000803e3d6000fd5b50505050619a07565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359cbd6fe84846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b838110156199a1578082015181840152602081019050619986565b50505050905090810190601f1680156199ce5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156199ee57600080fd5b505af1158015619a02573d6000803e3d6000fd5b505050505b505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663abf5739f8484619a5786619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015619aca578082015181840152602081019050619aaf565b50505050905090810190601f168015619af75780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b83811015619b30578082015181840152602081019050619b15565b50505050905090810190601f168015619b5d5780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015619b96578082015181840152602081019050619b7b565b50505050905090810190601f168015619bc35780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b158015619be457600080fd5b505afa158015619bf8573d6000803e3d6000fd5b505050506040513d6020811015619c0e57600080fd5b8101908080519060200190929190505050905092915050565b6060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663177c8d8a836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619cd3578082015181840152602081019050619cb8565b50505050905090810190601f168015619d005780820380516001836020036101000a031916815260200191505b509250505060006040518083038186803b158015619d1d57600080fd5b505afa158015619d31573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015619d5b57600080fd5b810190808051640100000000811115619d7357600080fd5b82810190506020810184811115619d8957600080fd5b8151856001820283011164010000000082111715619da657600080fd5b50509291905050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10619df657803560ff1916838001178555619e24565b82800160010185558215619e24579182015b82811115619e23578235825591602001919060010190619e08565b5b509050619e319190619e35565b5090565b619e5791905b80821115619e53576000816000905550600101619e3b565b5090565b9056fe696e76616c696420616374696f6e2e206f7065726174696f6e206e6f7420616c6c6f77656463616e2062652063616c6c656420627920696e7465726661636520636f6e7472616374206f6e6c796163636f756e74206973206e6f742061206e6574776f726b2061646d696e206163636f756e746163636f756e74206973206e6f742061206f72672061646d696e206163636f756e74a165627a7a723058201cfc4043c31882758609d4d19ea314d7cb2a97d0aad47c021996fe1b795b5a1a0029` + +// DeployPermImpl deploys a new Ethereum contract, binding an instance of PermImpl to it. +func DeployPermImpl(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address, _orgManager common.Address, _rolesManager common.Address, _accountManager common.Address, _voterManager common.Address, _nodeManager common.Address) (common.Address, *types.Transaction, *PermImpl, error) { + parsed, err := abi.JSON(strings.NewReader(PermImplABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PermImplBin), backend, _permUpgradable, _orgManager, _rolesManager, _accountManager, _voterManager, _nodeManager) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PermImpl{PermImplCaller: PermImplCaller{contract: contract}, PermImplTransactor: PermImplTransactor{contract: contract}, PermImplFilterer: PermImplFilterer{contract: contract}}, nil +} + +// PermImpl is an auto generated Go binding around an Ethereum contract. +type PermImpl struct { + PermImplCaller // Read-only binding to the contract + PermImplTransactor // Write-only binding to the contract + PermImplFilterer // Log filterer for contract events +} + +// PermImplCaller is an auto generated read-only Go binding around an Ethereum contract. +type PermImplCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermImplTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PermImplTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermImplFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PermImplFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermImplSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PermImplSession struct { + Contract *PermImpl // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermImplCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PermImplCallerSession struct { + Contract *PermImplCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PermImplTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PermImplTransactorSession struct { + Contract *PermImplTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermImplRaw is an auto generated low-level Go binding around an Ethereum contract. +type PermImplRaw struct { + Contract *PermImpl // Generic contract binding to access the raw methods on +} + +// PermImplCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PermImplCallerRaw struct { + Contract *PermImplCaller // Generic read-only contract binding to access the raw methods on +} + +// PermImplTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PermImplTransactorRaw struct { + Contract *PermImplTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPermImpl creates a new instance of PermImpl, bound to a specific deployed contract. +func NewPermImpl(address common.Address, backend bind.ContractBackend) (*PermImpl, error) { + contract, err := bindPermImpl(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PermImpl{PermImplCaller: PermImplCaller{contract: contract}, PermImplTransactor: PermImplTransactor{contract: contract}, PermImplFilterer: PermImplFilterer{contract: contract}}, nil +} + +// NewPermImplCaller creates a new read-only instance of PermImpl, bound to a specific deployed contract. +func NewPermImplCaller(address common.Address, caller bind.ContractCaller) (*PermImplCaller, error) { + contract, err := bindPermImpl(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PermImplCaller{contract: contract}, nil +} + +// NewPermImplTransactor creates a new write-only instance of PermImpl, bound to a specific deployed contract. +func NewPermImplTransactor(address common.Address, transactor bind.ContractTransactor) (*PermImplTransactor, error) { + contract, err := bindPermImpl(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PermImplTransactor{contract: contract}, nil +} + +// NewPermImplFilterer creates a new log filterer instance of PermImpl, bound to a specific deployed contract. +func NewPermImplFilterer(address common.Address, filterer bind.ContractFilterer) (*PermImplFilterer, error) { + contract, err := bindPermImpl(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PermImplFilterer{contract: contract}, nil +} + +// bindPermImpl binds a generic wrapper to an already deployed contract. +func bindPermImpl(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(PermImplABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermImpl *PermImplRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermImpl.Contract.PermImplCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermImpl *PermImplRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermImpl.Contract.PermImplTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermImpl *PermImplRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermImpl.Contract.PermImplTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermImpl *PermImplCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermImpl.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermImpl *PermImplTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermImpl.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermImpl *PermImplTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermImpl.Contract.contract.Transact(opts, method, params...) +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermImpl *PermImplCaller) GetNetworkBootStatus(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermImpl.contract.Call(opts, out, "getNetworkBootStatus") + return *ret0, err +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermImpl *PermImplSession) GetNetworkBootStatus() (bool, error) { + return _PermImpl.Contract.GetNetworkBootStatus(&_PermImpl.CallOpts) +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermImpl *PermImplCallerSession) GetNetworkBootStatus() (bool, error) { + return _PermImpl.Contract.GetNetworkBootStatus(&_PermImpl.CallOpts) +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermImpl *PermImplCaller) GetPendingOp(opts *bind.CallOpts, _orgId string) (string, string, common.Address, *big.Int, error) { + var ( + ret0 = new(string) + ret1 = new(string) + ret2 = new(common.Address) + ret3 = new(*big.Int) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + } + err := _PermImpl.contract.Call(opts, out, "getPendingOp", _orgId) + return *ret0, *ret1, *ret2, *ret3, err +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermImpl *PermImplSession) GetPendingOp(_orgId string) (string, string, common.Address, *big.Int, error) { + return _PermImpl.Contract.GetPendingOp(&_PermImpl.CallOpts, _orgId) +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermImpl *PermImplCallerSession) GetPendingOp(_orgId string) (string, string, common.Address, *big.Int, error) { + return _PermImpl.Contract.GetPendingOp(&_PermImpl.CallOpts, _orgId) +} + +// GetPolicyDetails is a free data retrieval call binding the contract method 0xcc9ba6fa. +// +// Solidity: function getPolicyDetails() constant returns(string, string, string, bool) +func (_PermImpl *PermImplCaller) GetPolicyDetails(opts *bind.CallOpts) (string, string, string, bool, error) { + var ( + ret0 = new(string) + ret1 = new(string) + ret2 = new(string) + ret3 = new(bool) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + } + err := _PermImpl.contract.Call(opts, out, "getPolicyDetails") + return *ret0, *ret1, *ret2, *ret3, err +} + +// GetPolicyDetails is a free data retrieval call binding the contract method 0xcc9ba6fa. +// +// Solidity: function getPolicyDetails() constant returns(string, string, string, bool) +func (_PermImpl *PermImplSession) GetPolicyDetails() (string, string, string, bool, error) { + return _PermImpl.Contract.GetPolicyDetails(&_PermImpl.CallOpts) +} + +// GetPolicyDetails is a free data retrieval call binding the contract method 0xcc9ba6fa. +// +// Solidity: function getPolicyDetails() constant returns(string, string, string, bool) +func (_PermImpl *PermImplCallerSession) GetPolicyDetails() (string, string, string, bool, error) { + return _PermImpl.Contract.GetPolicyDetails(&_PermImpl.CallOpts) +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermImpl *PermImplCaller) IsNetworkAdmin(opts *bind.CallOpts, _account common.Address) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermImpl.contract.Call(opts, out, "isNetworkAdmin", _account) + return *ret0, err +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermImpl *PermImplSession) IsNetworkAdmin(_account common.Address) (bool, error) { + return _PermImpl.Contract.IsNetworkAdmin(&_PermImpl.CallOpts, _account) +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermImpl *PermImplCallerSession) IsNetworkAdmin(_account common.Address) (bool, error) { + return _PermImpl.Contract.IsNetworkAdmin(&_PermImpl.CallOpts, _account) +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplCaller) IsOrgAdmin(opts *bind.CallOpts, _account common.Address, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermImpl.contract.Call(opts, out, "isOrgAdmin", _account, _orgId) + return *ret0, err +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplSession) IsOrgAdmin(_account common.Address, _orgId string) (bool, error) { + return _PermImpl.Contract.IsOrgAdmin(&_PermImpl.CallOpts, _account, _orgId) +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplCallerSession) IsOrgAdmin(_account common.Address, _orgId string) (bool, error) { + return _PermImpl.Contract.IsOrgAdmin(&_PermImpl.CallOpts, _account, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplCaller) ValidateAccount(opts *bind.CallOpts, _account common.Address, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermImpl.contract.Call(opts, out, "validateAccount", _account, _orgId) + return *ret0, err +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _PermImpl.Contract.ValidateAccount(&_PermImpl.CallOpts, _account, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermImpl *PermImplCallerSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _PermImpl.Contract.ValidateAccount(&_PermImpl.CallOpts, _account, _orgId) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_account address) returns() +func (_PermImpl *PermImplTransactor) AddAdminAccount(opts *bind.TransactOpts, _account common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addAdminAccount", _account) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_account address) returns() +func (_PermImpl *PermImplSession) AddAdminAccount(_account common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddAdminAccount(&_PermImpl.TransactOpts, _account) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_account address) returns() +func (_PermImpl *PermImplTransactorSession) AddAdminAccount(_account common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddAdminAccount(&_PermImpl.TransactOpts, _account) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermImpl *PermImplTransactor) AddAdminNode(opts *bind.TransactOpts, _enodeId string) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addAdminNode", _enodeId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermImpl *PermImplSession) AddAdminNode(_enodeId string) (*types.Transaction, error) { + return _PermImpl.Contract.AddAdminNode(&_PermImpl.TransactOpts, _enodeId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermImpl *PermImplTransactorSession) AddAdminNode(_enodeId string) (*types.Transaction, error) { + return _PermImpl.Contract.AddAdminNode(&_PermImpl.TransactOpts, _enodeId) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x1b04c276. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool, _caller address) returns() +func (_PermImpl *PermImplTransactor) AddNewRole(opts *bind.TransactOpts, _roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addNewRole", _roleId, _orgId, _access, _voter, _admin, _caller) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x1b04c276. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool, _caller address) returns() +func (_PermImpl *PermImplSession) AddNewRole(_roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddNewRole(&_PermImpl.TransactOpts, _roleId, _orgId, _access, _voter, _admin, _caller) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x1b04c276. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AddNewRole(_roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddNewRole(&_PermImpl.TransactOpts, _roleId, _orgId, _access, _voter, _admin, _caller) +} + +// AddNode is a paid mutator transaction binding the contract method 0x59a260a3. +// +// Solidity: function addNode(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) AddNode(opts *bind.TransactOpts, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addNode", _orgId, _enodeId, _caller) +} + +// AddNode is a paid mutator transaction binding the contract method 0x59a260a3. +// +// Solidity: function addNode(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplSession) AddNode(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddNode(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// AddNode is a paid mutator transaction binding the contract method 0x59a260a3. +// +// Solidity: function addNode(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AddNode(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddNode(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf922f802. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactor) AddOrg(opts *bind.TransactOpts, _orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addOrg", _orgId, _enodeId, _account, _caller) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf922f802. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplSession) AddOrg(_orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddOrg(&_PermImpl.TransactOpts, _orgId, _enodeId, _account, _caller) +} + +// AddOrg is a paid mutator transaction binding the contract method 0xf922f802. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AddOrg(_orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddOrg(&_PermImpl.TransactOpts, _orgId, _enodeId, _account, _caller) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0xa64d2860. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) AddSubOrg(opts *bind.TransactOpts, _pOrgId string, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "addSubOrg", _pOrgId, _orgId, _enodeId, _caller) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0xa64d2860. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplSession) AddSubOrg(_pOrgId string, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddSubOrg(&_PermImpl.TransactOpts, _pOrgId, _orgId, _enodeId, _caller) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0xa64d2860. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AddSubOrg(_pOrgId string, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AddSubOrg(&_PermImpl.TransactOpts, _pOrgId, _orgId, _enodeId, _caller) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x88843041. +// +// Solidity: function approveAdminRole(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactor) ApproveAdminRole(opts *bind.TransactOpts, _orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "approveAdminRole", _orgId, _account, _caller) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x88843041. +// +// Solidity: function approveAdminRole(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplSession) ApproveAdminRole(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveAdminRole(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x88843041. +// +// Solidity: function approveAdminRole(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) ApproveAdminRole(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveAdminRole(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x4b20f45f. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactor) ApproveBlacklistedAccountRecovery(opts *bind.TransactOpts, _orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "approveBlacklistedAccountRecovery", _orgId, _account, _caller) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x4b20f45f. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplSession) ApproveBlacklistedAccountRecovery(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveBlacklistedAccountRecovery(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x4b20f45f. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) ApproveBlacklistedAccountRecovery(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveBlacklistedAccountRecovery(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x655a8ef5. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) ApproveBlacklistedNodeRecovery(opts *bind.TransactOpts, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "approveBlacklistedNodeRecovery", _orgId, _enodeId, _caller) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x655a8ef5. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplSession) ApproveBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveBlacklistedNodeRecovery(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x655a8ef5. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) ApproveBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveBlacklistedNodeRecovery(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x3bc07dea. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactor) ApproveOrg(opts *bind.TransactOpts, _orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "approveOrg", _orgId, _enodeId, _account, _caller) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x3bc07dea. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplSession) ApproveOrg(_orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveOrg(&_PermImpl.TransactOpts, _orgId, _enodeId, _account, _caller) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x3bc07dea. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) ApproveOrg(_orgId string, _enodeId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveOrg(&_PermImpl.TransactOpts, _orgId, _enodeId, _account, _caller) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0xb5546564. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactor) ApproveOrgStatus(opts *bind.TransactOpts, _orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "approveOrgStatus", _orgId, _action, _caller) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0xb5546564. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplSession) ApproveOrgStatus(_orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveOrgStatus(&_PermImpl.TransactOpts, _orgId, _action, _caller) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0xb5546564. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) ApproveOrgStatus(_orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.ApproveOrgStatus(&_PermImpl.TransactOpts, _orgId, _action, _caller) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x8baa8191. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) AssignAccountRole(opts *bind.TransactOpts, _account common.Address, _orgId string, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "assignAccountRole", _account, _orgId, _roleId, _caller) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x8baa8191. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _caller address) returns() +func (_PermImpl *PermImplSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AssignAccountRole(&_PermImpl.TransactOpts, _account, _orgId, _roleId, _caller) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x8baa8191. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AssignAccountRole(&_PermImpl.TransactOpts, _account, _orgId, _roleId, _caller) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x404bf3eb. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) AssignAdminRole(opts *bind.TransactOpts, _orgId string, _account common.Address, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "assignAdminRole", _orgId, _account, _roleId, _caller) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x404bf3eb. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string, _caller address) returns() +func (_PermImpl *PermImplSession) AssignAdminRole(_orgId string, _account common.Address, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AssignAdminRole(&_PermImpl.TransactOpts, _orgId, _account, _roleId, _caller) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x404bf3eb. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) AssignAdminRole(_orgId string, _account common.Address, _roleId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.AssignAdminRole(&_PermImpl.TransactOpts, _orgId, _account, _roleId, _caller) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermImpl *PermImplTransactor) Init(opts *bind.TransactOpts, _breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "init", _breadth, _depth) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermImpl *PermImplSession) Init(_breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermImpl.Contract.Init(&_PermImpl.TransactOpts, _breadth, _depth) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermImpl *PermImplTransactorSession) Init(_breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermImpl.Contract.Init(&_PermImpl.TransactOpts, _breadth, _depth) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0x5ca5adbe. +// +// Solidity: function removeRole(_roleId string, _orgId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) RemoveRole(opts *bind.TransactOpts, _roleId string, _orgId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "removeRole", _roleId, _orgId, _caller) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0x5ca5adbe. +// +// Solidity: function removeRole(_roleId string, _orgId string, _caller address) returns() +func (_PermImpl *PermImplSession) RemoveRole(_roleId string, _orgId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.RemoveRole(&_PermImpl.TransactOpts, _roleId, _orgId, _caller) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0x5ca5adbe. +// +// Solidity: function removeRole(_roleId string, _orgId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) RemoveRole(_roleId string, _orgId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.RemoveRole(&_PermImpl.TransactOpts, _roleId, _orgId, _caller) +} + +// SetMigrationPolicy is a paid mutator transaction binding the contract method 0xf5ad584a. +// +// Solidity: function setMigrationPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) returns() +func (_PermImpl *PermImplTransactor) SetMigrationPolicy(opts *bind.TransactOpts, _nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "setMigrationPolicy", _nwAdminOrg, _nwAdminRole, _oAdminRole, _networkBootStatus) +} + +// SetMigrationPolicy is a paid mutator transaction binding the contract method 0xf5ad584a. +// +// Solidity: function setMigrationPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) returns() +func (_PermImpl *PermImplSession) SetMigrationPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) (*types.Transaction, error) { + return _PermImpl.Contract.SetMigrationPolicy(&_PermImpl.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole, _networkBootStatus) +} + +// SetMigrationPolicy is a paid mutator transaction binding the contract method 0xf5ad584a. +// +// Solidity: function setMigrationPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) returns() +func (_PermImpl *PermImplTransactorSession) SetMigrationPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string, _networkBootStatus bool) (*types.Transaction, error) { + return _PermImpl.Contract.SetMigrationPolicy(&_PermImpl.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole, _networkBootStatus) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermImpl *PermImplTransactor) SetPolicy(opts *bind.TransactOpts, _nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "setPolicy", _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermImpl *PermImplSession) SetPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermImpl.Contract.SetPolicy(&_PermImpl.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermImpl *PermImplTransactorSession) SetPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermImpl.Contract.SetPolicy(&_PermImpl.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x1c249912. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactor) StartBlacklistedAccountRecovery(opts *bind.TransactOpts, _orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "startBlacklistedAccountRecovery", _orgId, _account, _caller) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x1c249912. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplSession) StartBlacklistedAccountRecovery(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.StartBlacklistedAccountRecovery(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x1c249912. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) StartBlacklistedAccountRecovery(_orgId string, _account common.Address, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.StartBlacklistedAccountRecovery(&_PermImpl.TransactOpts, _orgId, _account, _caller) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0xc3dc8e09. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactor) StartBlacklistedNodeRecovery(opts *bind.TransactOpts, _orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "startBlacklistedNodeRecovery", _orgId, _enodeId, _caller) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0xc3dc8e09. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplSession) StartBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.StartBlacklistedNodeRecovery(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0xc3dc8e09. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) StartBlacklistedNodeRecovery(_orgId string, _enodeId string, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.StartBlacklistedNodeRecovery(&_PermImpl.TransactOpts, _orgId, _enodeId, _caller) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x04e81f1e. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactor) UpdateAccountStatus(opts *bind.TransactOpts, _orgId string, _account common.Address, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "updateAccountStatus", _orgId, _account, _action, _caller) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x04e81f1e. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256, _caller address) returns() +func (_PermImpl *PermImplSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateAccountStatus(&_PermImpl.TransactOpts, _orgId, _account, _action, _caller) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x04e81f1e. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateAccountStatus(&_PermImpl.TransactOpts, _orgId, _account, _action, _caller) +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermImpl *PermImplTransactor) UpdateNetworkBootStatus(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "updateNetworkBootStatus") +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermImpl *PermImplSession) UpdateNetworkBootStatus() (*types.Transaction, error) { + return _PermImpl.Contract.UpdateNetworkBootStatus(&_PermImpl.TransactOpts) +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermImpl *PermImplTransactorSession) UpdateNetworkBootStatus() (*types.Transaction, error) { + return _PermImpl.Contract.UpdateNetworkBootStatus(&_PermImpl.TransactOpts) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0xdbfad711. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactor) UpdateNodeStatus(opts *bind.TransactOpts, _orgId string, _enodeId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "updateNodeStatus", _orgId, _enodeId, _action, _caller) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0xdbfad711. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplSession) UpdateNodeStatus(_orgId string, _enodeId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateNodeStatus(&_PermImpl.TransactOpts, _orgId, _enodeId, _action, _caller) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0xdbfad711. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) UpdateNodeStatus(_orgId string, _enodeId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateNodeStatus(&_PermImpl.TransactOpts, _orgId, _enodeId, _action, _caller) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0x3cf5f33b. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactor) UpdateOrgStatus(opts *bind.TransactOpts, _orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.contract.Transact(opts, "updateOrgStatus", _orgId, _action, _caller) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0x3cf5f33b. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplSession) UpdateOrgStatus(_orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateOrgStatus(&_PermImpl.TransactOpts, _orgId, _action, _caller) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0x3cf5f33b. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256, _caller address) returns() +func (_PermImpl *PermImplTransactorSession) UpdateOrgStatus(_orgId string, _action *big.Int, _caller common.Address) (*types.Transaction, error) { + return _PermImpl.Contract.UpdateOrgStatus(&_PermImpl.TransactOpts, _orgId, _action, _caller) +} + +// PermImplPermissionsInitializedIterator is returned from FilterPermissionsInitialized and is used to iterate over the raw logs and unpacked data for PermissionsInitialized events raised by the PermImpl contract. +type PermImplPermissionsInitializedIterator struct { + Event *PermImplPermissionsInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PermImplPermissionsInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PermImplPermissionsInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PermImplPermissionsInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PermImplPermissionsInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PermImplPermissionsInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PermImplPermissionsInitialized represents a PermissionsInitialized event raised by the PermImpl contract. +type PermImplPermissionsInitialized struct { + NetworkBootStatus bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPermissionsInitialized is a free log retrieval operation binding the contract event 0x04f651be6fb8fc575d94591e56e9f6e66e33ef23e949765918b3bdae50c617cf. +// +// Solidity: e PermissionsInitialized(_networkBootStatus bool) +func (_PermImpl *PermImplFilterer) FilterPermissionsInitialized(opts *bind.FilterOpts) (*PermImplPermissionsInitializedIterator, error) { + + logs, sub, err := _PermImpl.contract.FilterLogs(opts, "PermissionsInitialized") + if err != nil { + return nil, err + } + return &PermImplPermissionsInitializedIterator{contract: _PermImpl.contract, event: "PermissionsInitialized", logs: logs, sub: sub}, nil +} + +// WatchPermissionsInitialized is a free log subscription operation binding the contract event 0x04f651be6fb8fc575d94591e56e9f6e66e33ef23e949765918b3bdae50c617cf. +// +// Solidity: e PermissionsInitialized(_networkBootStatus bool) +func (_PermImpl *PermImplFilterer) WatchPermissionsInitialized(opts *bind.WatchOpts, sink chan<- *PermImplPermissionsInitialized) (event.Subscription, error) { + + logs, sub, err := _PermImpl.contract.WatchLogs(opts, "PermissionsInitialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PermImplPermissionsInitialized) + if err := _PermImpl.contract.UnpackLog(event, "PermissionsInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/bind/permission_interface.go b/permission/bind/permission_interface.go new file mode 100644 index 0000000000..ff694b18f3 --- /dev/null +++ b/permission/bind/permission_interface.go @@ -0,0 +1,836 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// PermInterfaceABI is the input ABI used to generate the binding from. +const PermInterfaceABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getPermissionsImpl\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateNodeStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"approveAdminRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_nwAdminOrg\",\"type\":\"string\"},{\"name\":\"_nwAdminRole\",\"type\":\"string\"},{\"name\":\"_oAdminRole\",\"type\":\"string\"}],\"name\":\"setPolicy\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_roleId\",\"type\":\"string\"}],\"name\":\"assignAccountRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"approveBlacklistedAccountRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"addAdminNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_roleId\",\"type\":\"string\"}],\"name\":\"assignAdminRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"updateNetworkBootStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNetworkBootStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_pOrgId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"addSubOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_acct\",\"type\":\"address\"}],\"name\":\"addAdminAccount\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_permImplementation\",\"type\":\"address\"}],\"name\":\"setPermImplementation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_access\",\"type\":\"uint256\"},{\"name\":\"_voter\",\"type\":\"bool\"},{\"name\":\"_admin\",\"type\":\"bool\"}],\"name\":\"addNewRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"approveBlacklistedNodeRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"approveOrgStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"validateAccount\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"approveOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateAccountStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"startBlacklistedNodeRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"addOrg\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"isOrgAdmin\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_breadth\",\"type\":\"uint256\"},{\"name\":\"_depth\",\"type\":\"uint256\"}],\"name\":\"init\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"removeRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"startBlacklistedAccountRecovery\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"}],\"name\":\"addNode\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_action\",\"type\":\"uint256\"}],\"name\":\"updateOrgStatus\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isNetworkAdmin\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"getPendingOp\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permImplUpgradeable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" + +// PermInterfaceBin is the compiled bytecode used for deploying new contracts. +const PermInterfaceBin = `608060405234801561001057600080fd5b506040516020806138138339810180604052602081101561003057600080fd5b810190808051906020019092919050505080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613781806100926000396000f3fe608060405234801561001057600080fd5b50600436106101ec576000357c0100000000000000000000000000000000000000000000000000000000900480635adbfa7a116101215780639bd38101116100bf578063a97a44061161008e578063a97a44061461123b578063bb3b6e8014611309578063d1aa0c201461138c578063f346a3a7146113e8576101ec565b80639bd3810114610feb578063a5843f081461109c578063a6343012146110d4578063a97914bf146111a2576101ec565b80637e461258116100fb5780637e46125814610c9e57806384b7a84a14610d8c5780638cb58ef314610e2f5780638f362a3e14610efd576101ec565b80635adbfa7a14610a9c5780635be9672c14610b6a5780636b568d7614610bed576101ec565b806343de646c1161018e5780634cff819e116101685780634cff819e146108015780634fe57e7a14610924578063511bbd9f1461096857806351f604c3146109ac576101ec565b806343de646c146106cf57806344478e79146107bd5780634cbfa82e146107df576101ec565b80631b610220116101ca5780631b610220146103ac5780632f7f0a12146104cf5780633e239b23146105bd5780633f25c28814610656576101ec565b806303ed6933146101f15780630cc501461461023b57806316724c4414610313575b600080fd5b6101f9611580565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103116004803603606081101561025157600080fd5b810190808035906020019064010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460018302840111640100000000831117156102a257600080fd5b9091929391929390803590602001906401000000008111156102c357600080fd5b8201836020820111156102d557600080fd5b803590602001918460018302840111640100000000831117156102f757600080fd5b9091929391929390803590602001909291905050506115a9565b005b6103aa6004803603604081101561032957600080fd5b810190808035906020019064010000000081111561034657600080fd5b82018360208201111561035857600080fd5b8035906020019184600183028401116401000000008311171561037a57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116f4565b005b6104cd600480360360608110156103c257600080fd5b81019080803590602001906401000000008111156103df57600080fd5b8201836020820111156103f157600080fd5b8035906020019184600183028401116401000000008311171561041357600080fd5b90919293919293908035906020019064010000000081111561043457600080fd5b82018360208201111561044657600080fd5b8035906020019184600183028401116401000000008311171561046857600080fd5b90919293919293908035906020019064010000000081111561048957600080fd5b82018360208201111561049b57600080fd5b803590602001918460018302840111640100000000831117156104bd57600080fd5b9091929391929390505050611835565b005b6105bb600480360360608110156104e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561052257600080fd5b82018360208201111561053457600080fd5b8035906020019184600183028401116401000000008311171561055657600080fd5b90919293919293908035906020019064010000000081111561057757600080fd5b82018360208201111561058957600080fd5b803590602001918460018302840111640100000000831117156105ab57600080fd5b9091929391929390505050611979565b005b610654600480360360408110156105d357600080fd5b81019080803590602001906401000000008111156105f057600080fd5b82018360208201111561060257600080fd5b8035906020019184600183028401116401000000008311171561062457600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611af0565b005b6106cd6004803603602081101561066c57600080fd5b810190808035906020019064010000000081111561068957600080fd5b82018360208201111561069b57600080fd5b803590602001918460018302840111640100000000831117156106bd57600080fd5b9091929391929390505050611c31565b005b6107bb600480360360608110156106e557600080fd5b810190808035906020019064010000000081111561070257600080fd5b82018360208201111561071457600080fd5b8035906020019184600183028401116401000000008311171561073657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561077757600080fd5b82018360208201111561078957600080fd5b803590602001918460018302840111640100000000831117156107ab57600080fd5b9091929391929390505050611d09565b005b6107c5611e80565b604051808215151515815260200191505060405180910390f35b6107e7611f47565b604051808215151515815260200191505060405180910390f35b6109226004803603606081101561081757600080fd5b810190808035906020019064010000000081111561083457600080fd5b82018360208201111561084657600080fd5b8035906020019184600183028401116401000000008311171561086857600080fd5b90919293919293908035906020019064010000000081111561088957600080fd5b82018360208201111561089b57600080fd5b803590602001918460018302840111640100000000831117156108bd57600080fd5b9091929391929390803590602001906401000000008111156108de57600080fd5b8201836020820111156108f057600080fd5b8035906020019184600183028401116401000000008311171561091257600080fd5b909192939192939050505061200c565b005b6109666004803603602081101561093a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612184565b005b6109aa6004803603602081101561097e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061225b565b005b610a9a600480360360a08110156109c257600080fd5b81019080803590602001906401000000008111156109df57600080fd5b8201836020820111156109f157600080fd5b80359060200191846001830284011164010000000083111715610a1357600080fd5b909192939192939080359060200190640100000000811115610a3457600080fd5b820183602082011115610a4657600080fd5b80359060200191846001830284011164010000000083111715610a6857600080fd5b909192939192939080359060200190929190803515159060200190929190803515159060200190929190505050612363565b005b610b6860048036036040811015610ab257600080fd5b8101908080359060200190640100000000811115610acf57600080fd5b820183602082011115610ae157600080fd5b80359060200191846001830284011164010000000083111715610b0357600080fd5b909192939192939080359060200190640100000000811115610b2457600080fd5b820183602082011115610b3657600080fd5b80359060200191846001830284011164010000000083111715610b5857600080fd5b90919293919293905050506124c8565b005b610beb60048036036040811015610b8057600080fd5b8101908080359060200190640100000000811115610b9d57600080fd5b820183602082011115610baf57600080fd5b80359060200191846001830284011164010000000083111715610bd157600080fd5b90919293919293908035906020019092919050505061260a565b005b610c8460048036036040811015610c0357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610c4057600080fd5b820183602082011115610c5257600080fd5b80359060200191846001830284011164010000000083111715610c7457600080fd5b909192939192939050505061271f565b604051808215151515815260200191505060405180910390f35b610d8a60048036036060811015610cb457600080fd5b8101908080359060200190640100000000811115610cd157600080fd5b820183602082011115610ce357600080fd5b80359060200191846001830284011164010000000083111715610d0557600080fd5b909192939192939080359060200190640100000000811115610d2657600080fd5b820183602082011115610d3857600080fd5b80359060200191846001830284011164010000000083111715610d5a57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612853565b005b610e2d60048036036060811015610da257600080fd5b8101908080359060200190640100000000811115610dbf57600080fd5b820183602082011115610dd157600080fd5b80359060200191846001830284011164010000000083111715610df357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506129ca565b005b610efb60048036036040811015610e4557600080fd5b8101908080359060200190640100000000811115610e6257600080fd5b820183602082011115610e7457600080fd5b80359060200191846001830284011164010000000083111715610e9657600080fd5b909192939192939080359060200190640100000000811115610eb757600080fd5b820183602082011115610ec957600080fd5b80359060200191846001830284011164010000000083111715610eeb57600080fd5b9091929391929390505050612b14565b005b610fe960048036036060811015610f1357600080fd5b8101908080359060200190640100000000811115610f3057600080fd5b820183602082011115610f4257600080fd5b80359060200191846001830284011164010000000083111715610f6457600080fd5b909192939192939080359060200190640100000000811115610f8557600080fd5b820183602082011115610f9757600080fd5b80359060200191846001830284011164010000000083111715610fb957600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c56565b005b6110826004803603604081101561100157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561103e57600080fd5b82018360208201111561105057600080fd5b8035906020019184600183028401116401000000008311171561107257600080fd5b9091929391929390505050612dcd565b604051808215151515815260200191505060405180910390f35b6110d2600480360360408110156110b257600080fd5b810190808035906020019092919080359060200190929190505050612f01565b005b6111a0600480360360408110156110ea57600080fd5b810190808035906020019064010000000081111561110757600080fd5b82018360208201111561111957600080fd5b8035906020019184600183028401116401000000008311171561113b57600080fd5b90919293919293908035906020019064010000000081111561115c57600080fd5b82018360208201111561116e57600080fd5b8035906020019184600183028401116401000000008311171561119057600080fd5b9091929391929390505050612fb5565b005b611239600480360360408110156111b857600080fd5b81019080803590602001906401000000008111156111d557600080fd5b8201836020820111156111e757600080fd5b8035906020019184600183028401116401000000008311171561120957600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506130f7565b005b6113076004803603604081101561125157600080fd5b810190808035906020019064010000000081111561126e57600080fd5b82018360208201111561128057600080fd5b803590602001918460018302840111640100000000831117156112a257600080fd5b9091929391929390803590602001906401000000008111156112c357600080fd5b8201836020820111156112d557600080fd5b803590602001918460018302840111640100000000831117156112f757600080fd5b9091929391929390505050613238565b005b61138a6004803603604081101561131f57600080fd5b810190808035906020019064010000000081111561133c57600080fd5b82018360208201111561134e57600080fd5b8035906020019184600183028401116401000000008311171561137057600080fd5b90919293919293908035906020019092919050505061337a565b005b6113ce600480360360208110156113a257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061348f565b604051808215151515815260200191505060405180910390f35b61145f600480360360208110156113fe57600080fd5b810190808035906020019064010000000081111561141b57600080fd5b82018360208201111561142d57600080fd5b8035906020019184600183028401116401000000008311171561144f57600080fd5b909192939192939050505061358d565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156114db5780820151818401526020810190506114c0565b50505050905090810190601f1680156115085780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b83811015611541578082015181840152602081019050611526565b50505050905090810190601f16801561156e5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dbfad7118686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b1580156116d557600080fd5b505af11580156116e9573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166388843041848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561181857600080fd5b505af115801561182c573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b6102208787878787876040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018060200184810384528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509950505050505050505050600060405180830381600087803b15801561195957600080fd5b505af115801561196d573d6000803e3d6000fd5b50505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638baa81918686868686336040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015611ad157600080fd5b505af1158015611ae5573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b20f45f848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611c1457600080fd5b505af1158015611c28573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f25c28883836040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015611ced57600080fd5b505af1158015611d01573d6000803e3d6000fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663404bf3eb8686868686336040518763ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015611e6157600080fd5b505af1158015611e75573d6000803e3d6000fd5b505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166344478e796040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611f0757600080fd5b505af1158015611f1b573d6000803e3d6000fd5b505050506040513d6020811015611f3157600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634cbfa82e6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611fcc57600080fd5b505afa158015611fe0573d6000803e3d6000fd5b505050506040513d6020811015611ff657600080fd5b8101908080519060200190929190505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a64d2860878787878787336040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184810384528b8b82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508481038252878782818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b15801561216457600080fd5b505af1158015612178573d6000803e3d6000fd5b50505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634fe57e7a826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561224057600080fd5b505af1158015612254573d6000803e3d6000fd5b5050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b04c27688888888888888336040518963ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200187815260200186151515158152602001851515151581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183810383528b8b82818152602001925080828437600081840152601f19601f8201169050808301925050508381038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b1580156124a757600080fd5b505af11580156124bb573d6000803e3d6000fd5b5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663655a8ef585858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156125ec57600080fd5b505af1158015612600573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b5546564848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561270257600080fd5b505af1158015612716573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b568d768585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d602081101561283957600080fd5b810190808051906020019092919050505090509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633bc07dea8686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b1580156129ab57600080fd5b505af11580156129bf573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166304e81f1e85858585336040518663ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015612af657600080fd5b505af1158015612b0a573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3dc8e0985858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b158015612c3857600080fd5b505af1158015612c4c573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f922f8028686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612dae57600080fd5b505af1158015612dc2573d6000803e3d6000fd5b505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639bd381018585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060206040518083038186803b158015612ebd57600080fd5b505afa158015612ed1573d6000803e3d6000fd5b505050506040513d6020811015612ee757600080fd5b810190808051906020019092919050505090509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a5843f0883836040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182815260200192505050600060405180830381600087803b158015612f9957600080fd5b505af1158015612fad573d6000803e3d6000fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ca5adbe85858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156130d957600080fd5b505af11580156130ed573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c249912848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561321b57600080fd5b505af115801561322f573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359a260a385858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b15801561335c57600080fd5b505af1158015613370573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633cf5f33b848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561347257600080fd5b505af1158015613486573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1aa0c20836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561354b57600080fd5b505afa15801561355f573d6000803e3d6000fd5b505050506040513d602081101561357557600080fd5b81019080805190602001909291905050509050919050565b6060806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f346a3a787876040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561364d57600080fd5b505afa158015613661573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561368b57600080fd5b8101908080516401000000008111156136a357600080fd5b828101905060208101848111156136b957600080fd5b81518560018202830111640100000000821117156136d657600080fd5b505092919060200180516401000000008111156136f257600080fd5b8281019050602081018481111561370857600080fd5b815185600182028301116401000000008211171561372557600080fd5b5050929190602001805190602001909291908051906020019092919050505093509350935093509295919450925056fea165627a7a7230582049eecad3069ea93138ffdb59f1b6803feaa6cde89ea4ef7956f533e671354e340029` + +// DeployPermInterface deploys a new Ethereum contract, binding an instance of PermInterface to it. +func DeployPermInterface(auth *bind.TransactOpts, backend bind.ContractBackend, _permImplUpgradeable common.Address) (common.Address, *types.Transaction, *PermInterface, error) { + parsed, err := abi.JSON(strings.NewReader(PermInterfaceABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PermInterfaceBin), backend, _permImplUpgradeable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PermInterface{PermInterfaceCaller: PermInterfaceCaller{contract: contract}, PermInterfaceTransactor: PermInterfaceTransactor{contract: contract}, PermInterfaceFilterer: PermInterfaceFilterer{contract: contract}}, nil +} + +// PermInterface is an auto generated Go binding around an Ethereum contract. +type PermInterface struct { + PermInterfaceCaller // Read-only binding to the contract + PermInterfaceTransactor // Write-only binding to the contract + PermInterfaceFilterer // Log filterer for contract events +} + +// PermInterfaceCaller is an auto generated read-only Go binding around an Ethereum contract. +type PermInterfaceCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermInterfaceTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PermInterfaceTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermInterfaceFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PermInterfaceFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermInterfaceSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PermInterfaceSession struct { + Contract *PermInterface // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermInterfaceCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PermInterfaceCallerSession struct { + Contract *PermInterfaceCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PermInterfaceTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PermInterfaceTransactorSession struct { + Contract *PermInterfaceTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermInterfaceRaw is an auto generated low-level Go binding around an Ethereum contract. +type PermInterfaceRaw struct { + Contract *PermInterface // Generic contract binding to access the raw methods on +} + +// PermInterfaceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PermInterfaceCallerRaw struct { + Contract *PermInterfaceCaller // Generic read-only contract binding to access the raw methods on +} + +// PermInterfaceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PermInterfaceTransactorRaw struct { + Contract *PermInterfaceTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPermInterface creates a new instance of PermInterface, bound to a specific deployed contract. +func NewPermInterface(address common.Address, backend bind.ContractBackend) (*PermInterface, error) { + contract, err := bindPermInterface(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PermInterface{PermInterfaceCaller: PermInterfaceCaller{contract: contract}, PermInterfaceTransactor: PermInterfaceTransactor{contract: contract}, PermInterfaceFilterer: PermInterfaceFilterer{contract: contract}}, nil +} + +// NewPermInterfaceCaller creates a new read-only instance of PermInterface, bound to a specific deployed contract. +func NewPermInterfaceCaller(address common.Address, caller bind.ContractCaller) (*PermInterfaceCaller, error) { + contract, err := bindPermInterface(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PermInterfaceCaller{contract: contract}, nil +} + +// NewPermInterfaceTransactor creates a new write-only instance of PermInterface, bound to a specific deployed contract. +func NewPermInterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*PermInterfaceTransactor, error) { + contract, err := bindPermInterface(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PermInterfaceTransactor{contract: contract}, nil +} + +// NewPermInterfaceFilterer creates a new log filterer instance of PermInterface, bound to a specific deployed contract. +func NewPermInterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*PermInterfaceFilterer, error) { + contract, err := bindPermInterface(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PermInterfaceFilterer{contract: contract}, nil +} + +// bindPermInterface binds a generic wrapper to an already deployed contract. +func bindPermInterface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(PermInterfaceABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermInterface *PermInterfaceRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermInterface.Contract.PermInterfaceCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermInterface *PermInterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermInterface.Contract.PermInterfaceTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermInterface *PermInterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermInterface.Contract.PermInterfaceTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermInterface *PermInterfaceCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermInterface.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermInterface *PermInterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermInterface.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermInterface *PermInterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermInterface.Contract.contract.Transact(opts, method, params...) +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermInterface *PermInterfaceCaller) GetNetworkBootStatus(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermInterface.contract.Call(opts, out, "getNetworkBootStatus") + return *ret0, err +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermInterface *PermInterfaceSession) GetNetworkBootStatus() (bool, error) { + return _PermInterface.Contract.GetNetworkBootStatus(&_PermInterface.CallOpts) +} + +// GetNetworkBootStatus is a free data retrieval call binding the contract method 0x4cbfa82e. +// +// Solidity: function getNetworkBootStatus() constant returns(bool) +func (_PermInterface *PermInterfaceCallerSession) GetNetworkBootStatus() (bool, error) { + return _PermInterface.Contract.GetNetworkBootStatus(&_PermInterface.CallOpts) +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermInterface *PermInterfaceCaller) GetPendingOp(opts *bind.CallOpts, _orgId string) (string, string, common.Address, *big.Int, error) { + var ( + ret0 = new(string) + ret1 = new(string) + ret2 = new(common.Address) + ret3 = new(*big.Int) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + } + err := _PermInterface.contract.Call(opts, out, "getPendingOp", _orgId) + return *ret0, *ret1, *ret2, *ret3, err +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermInterface *PermInterfaceSession) GetPendingOp(_orgId string) (string, string, common.Address, *big.Int, error) { + return _PermInterface.Contract.GetPendingOp(&_PermInterface.CallOpts, _orgId) +} + +// GetPendingOp is a free data retrieval call binding the contract method 0xf346a3a7. +// +// Solidity: function getPendingOp(_orgId string) constant returns(string, string, address, uint256) +func (_PermInterface *PermInterfaceCallerSession) GetPendingOp(_orgId string) (string, string, common.Address, *big.Int, error) { + return _PermInterface.Contract.GetPendingOp(&_PermInterface.CallOpts, _orgId) +} + +// GetPermissionsImpl is a free data retrieval call binding the contract method 0x03ed6933. +// +// Solidity: function getPermissionsImpl() constant returns(address) +func (_PermInterface *PermInterfaceCaller) GetPermissionsImpl(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _PermInterface.contract.Call(opts, out, "getPermissionsImpl") + return *ret0, err +} + +// GetPermissionsImpl is a free data retrieval call binding the contract method 0x03ed6933. +// +// Solidity: function getPermissionsImpl() constant returns(address) +func (_PermInterface *PermInterfaceSession) GetPermissionsImpl() (common.Address, error) { + return _PermInterface.Contract.GetPermissionsImpl(&_PermInterface.CallOpts) +} + +// GetPermissionsImpl is a free data retrieval call binding the contract method 0x03ed6933. +// +// Solidity: function getPermissionsImpl() constant returns(address) +func (_PermInterface *PermInterfaceCallerSession) GetPermissionsImpl() (common.Address, error) { + return _PermInterface.Contract.GetPermissionsImpl(&_PermInterface.CallOpts) +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermInterface *PermInterfaceCaller) IsNetworkAdmin(opts *bind.CallOpts, _account common.Address) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermInterface.contract.Call(opts, out, "isNetworkAdmin", _account) + return *ret0, err +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermInterface *PermInterfaceSession) IsNetworkAdmin(_account common.Address) (bool, error) { + return _PermInterface.Contract.IsNetworkAdmin(&_PermInterface.CallOpts, _account) +} + +// IsNetworkAdmin is a free data retrieval call binding the contract method 0xd1aa0c20. +// +// Solidity: function isNetworkAdmin(_account address) constant returns(bool) +func (_PermInterface *PermInterfaceCallerSession) IsNetworkAdmin(_account common.Address) (bool, error) { + return _PermInterface.Contract.IsNetworkAdmin(&_PermInterface.CallOpts, _account) +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceCaller) IsOrgAdmin(opts *bind.CallOpts, _account common.Address, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermInterface.contract.Call(opts, out, "isOrgAdmin", _account, _orgId) + return *ret0, err +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceSession) IsOrgAdmin(_account common.Address, _orgId string) (bool, error) { + return _PermInterface.Contract.IsOrgAdmin(&_PermInterface.CallOpts, _account, _orgId) +} + +// IsOrgAdmin is a free data retrieval call binding the contract method 0x9bd38101. +// +// Solidity: function isOrgAdmin(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceCallerSession) IsOrgAdmin(_account common.Address, _orgId string) (bool, error) { + return _PermInterface.Contract.IsOrgAdmin(&_PermInterface.CallOpts, _account, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceCaller) ValidateAccount(opts *bind.CallOpts, _account common.Address, _orgId string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _PermInterface.contract.Call(opts, out, "validateAccount", _account, _orgId) + return *ret0, err +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _PermInterface.Contract.ValidateAccount(&_PermInterface.CallOpts, _account, _orgId) +} + +// ValidateAccount is a free data retrieval call binding the contract method 0x6b568d76. +// +// Solidity: function validateAccount(_account address, _orgId string) constant returns(bool) +func (_PermInterface *PermInterfaceCallerSession) ValidateAccount(_account common.Address, _orgId string) (bool, error) { + return _PermInterface.Contract.ValidateAccount(&_PermInterface.CallOpts, _account, _orgId) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_acct address) returns() +func (_PermInterface *PermInterfaceTransactor) AddAdminAccount(opts *bind.TransactOpts, _acct common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addAdminAccount", _acct) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_acct address) returns() +func (_PermInterface *PermInterfaceSession) AddAdminAccount(_acct common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.AddAdminAccount(&_PermInterface.TransactOpts, _acct) +} + +// AddAdminAccount is a paid mutator transaction binding the contract method 0x4fe57e7a. +// +// Solidity: function addAdminAccount(_acct address) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddAdminAccount(_acct common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.AddAdminAccount(&_PermInterface.TransactOpts, _acct) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermInterface *PermInterfaceTransactor) AddAdminNode(opts *bind.TransactOpts, _enodeId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addAdminNode", _enodeId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermInterface *PermInterfaceSession) AddAdminNode(_enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddAdminNode(&_PermInterface.TransactOpts, _enodeId) +} + +// AddAdminNode is a paid mutator transaction binding the contract method 0x3f25c288. +// +// Solidity: function addAdminNode(_enodeId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddAdminNode(_enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddAdminNode(&_PermInterface.TransactOpts, _enodeId) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x51f604c3. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool) returns() +func (_PermInterface *PermInterfaceTransactor) AddNewRole(opts *bind.TransactOpts, _roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addNewRole", _roleId, _orgId, _access, _voter, _admin) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x51f604c3. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool) returns() +func (_PermInterface *PermInterfaceSession) AddNewRole(_roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool) (*types.Transaction, error) { + return _PermInterface.Contract.AddNewRole(&_PermInterface.TransactOpts, _roleId, _orgId, _access, _voter, _admin) +} + +// AddNewRole is a paid mutator transaction binding the contract method 0x51f604c3. +// +// Solidity: function addNewRole(_roleId string, _orgId string, _access uint256, _voter bool, _admin bool) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddNewRole(_roleId string, _orgId string, _access *big.Int, _voter bool, _admin bool) (*types.Transaction, error) { + return _PermInterface.Contract.AddNewRole(&_PermInterface.TransactOpts, _roleId, _orgId, _access, _voter, _admin) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactor) AddNode(opts *bind.TransactOpts, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addNode", _orgId, _enodeId) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceSession) AddNode(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddNode(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// AddNode is a paid mutator transaction binding the contract method 0xa97a4406. +// +// Solidity: function addNode(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddNode(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddNode(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// AddOrg is a paid mutator transaction binding the contract method 0x8f362a3e. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactor) AddOrg(opts *bind.TransactOpts, _orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addOrg", _orgId, _enodeId, _account) +} + +// AddOrg is a paid mutator transaction binding the contract method 0x8f362a3e. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceSession) AddOrg(_orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.AddOrg(&_PermInterface.TransactOpts, _orgId, _enodeId, _account) +} + +// AddOrg is a paid mutator transaction binding the contract method 0x8f362a3e. +// +// Solidity: function addOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddOrg(_orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.AddOrg(&_PermInterface.TransactOpts, _orgId, _enodeId, _account) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x4cff819e. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactor) AddSubOrg(opts *bind.TransactOpts, _pOrgId string, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "addSubOrg", _pOrgId, _orgId, _enodeId) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x4cff819e. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceSession) AddSubOrg(_pOrgId string, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddSubOrg(&_PermInterface.TransactOpts, _pOrgId, _orgId, _enodeId) +} + +// AddSubOrg is a paid mutator transaction binding the contract method 0x4cff819e. +// +// Solidity: function addSubOrg(_pOrgId string, _orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) AddSubOrg(_pOrgId string, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.AddSubOrg(&_PermInterface.TransactOpts, _pOrgId, _orgId, _enodeId) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x16724c44. +// +// Solidity: function approveAdminRole(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactor) ApproveAdminRole(opts *bind.TransactOpts, _orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "approveAdminRole", _orgId, _account) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x16724c44. +// +// Solidity: function approveAdminRole(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceSession) ApproveAdminRole(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveAdminRole(&_PermInterface.TransactOpts, _orgId, _account) +} + +// ApproveAdminRole is a paid mutator transaction binding the contract method 0x16724c44. +// +// Solidity: function approveAdminRole(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactorSession) ApproveAdminRole(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveAdminRole(&_PermInterface.TransactOpts, _orgId, _account) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x3e239b23. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactor) ApproveBlacklistedAccountRecovery(opts *bind.TransactOpts, _orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "approveBlacklistedAccountRecovery", _orgId, _account) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x3e239b23. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceSession) ApproveBlacklistedAccountRecovery(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveBlacklistedAccountRecovery(&_PermInterface.TransactOpts, _orgId, _account) +} + +// ApproveBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0x3e239b23. +// +// Solidity: function approveBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactorSession) ApproveBlacklistedAccountRecovery(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveBlacklistedAccountRecovery(&_PermInterface.TransactOpts, _orgId, _account) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x5adbfa7a. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactor) ApproveBlacklistedNodeRecovery(opts *bind.TransactOpts, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "approveBlacklistedNodeRecovery", _orgId, _enodeId) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x5adbfa7a. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceSession) ApproveBlacklistedNodeRecovery(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveBlacklistedNodeRecovery(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// ApproveBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x5adbfa7a. +// +// Solidity: function approveBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) ApproveBlacklistedNodeRecovery(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveBlacklistedNodeRecovery(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x7e461258. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactor) ApproveOrg(opts *bind.TransactOpts, _orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "approveOrg", _orgId, _enodeId, _account) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x7e461258. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceSession) ApproveOrg(_orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveOrg(&_PermInterface.TransactOpts, _orgId, _enodeId, _account) +} + +// ApproveOrg is a paid mutator transaction binding the contract method 0x7e461258. +// +// Solidity: function approveOrg(_orgId string, _enodeId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactorSession) ApproveOrg(_orgId string, _enodeId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveOrg(&_PermInterface.TransactOpts, _orgId, _enodeId, _account) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0x5be9672c. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactor) ApproveOrgStatus(opts *bind.TransactOpts, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "approveOrgStatus", _orgId, _action) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0x5be9672c. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceSession) ApproveOrgStatus(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveOrgStatus(&_PermInterface.TransactOpts, _orgId, _action) +} + +// ApproveOrgStatus is a paid mutator transaction binding the contract method 0x5be9672c. +// +// Solidity: function approveOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactorSession) ApproveOrgStatus(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.ApproveOrgStatus(&_PermInterface.TransactOpts, _orgId, _action) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x2f7f0a12. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string) returns() +func (_PermInterface *PermInterfaceTransactor) AssignAccountRole(opts *bind.TransactOpts, _account common.Address, _orgId string, _roleId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "assignAccountRole", _account, _orgId, _roleId) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x2f7f0a12. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string) returns() +func (_PermInterface *PermInterfaceSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string) (*types.Transaction, error) { + return _PermInterface.Contract.AssignAccountRole(&_PermInterface.TransactOpts, _account, _orgId, _roleId) +} + +// AssignAccountRole is a paid mutator transaction binding the contract method 0x2f7f0a12. +// +// Solidity: function assignAccountRole(_account address, _orgId string, _roleId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) AssignAccountRole(_account common.Address, _orgId string, _roleId string) (*types.Transaction, error) { + return _PermInterface.Contract.AssignAccountRole(&_PermInterface.TransactOpts, _account, _orgId, _roleId) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x43de646c. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string) returns() +func (_PermInterface *PermInterfaceTransactor) AssignAdminRole(opts *bind.TransactOpts, _orgId string, _account common.Address, _roleId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "assignAdminRole", _orgId, _account, _roleId) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x43de646c. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string) returns() +func (_PermInterface *PermInterfaceSession) AssignAdminRole(_orgId string, _account common.Address, _roleId string) (*types.Transaction, error) { + return _PermInterface.Contract.AssignAdminRole(&_PermInterface.TransactOpts, _orgId, _account, _roleId) +} + +// AssignAdminRole is a paid mutator transaction binding the contract method 0x43de646c. +// +// Solidity: function assignAdminRole(_orgId string, _account address, _roleId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) AssignAdminRole(_orgId string, _account common.Address, _roleId string) (*types.Transaction, error) { + return _PermInterface.Contract.AssignAdminRole(&_PermInterface.TransactOpts, _orgId, _account, _roleId) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermInterface *PermInterfaceTransactor) Init(opts *bind.TransactOpts, _breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "init", _breadth, _depth) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermInterface *PermInterfaceSession) Init(_breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.Init(&_PermInterface.TransactOpts, _breadth, _depth) +} + +// Init is a paid mutator transaction binding the contract method 0xa5843f08. +// +// Solidity: function init(_breadth uint256, _depth uint256) returns() +func (_PermInterface *PermInterfaceTransactorSession) Init(_breadth *big.Int, _depth *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.Init(&_PermInterface.TransactOpts, _breadth, _depth) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_PermInterface *PermInterfaceTransactor) RemoveRole(opts *bind.TransactOpts, _roleId string, _orgId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "removeRole", _roleId, _orgId) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_PermInterface *PermInterfaceSession) RemoveRole(_roleId string, _orgId string) (*types.Transaction, error) { + return _PermInterface.Contract.RemoveRole(&_PermInterface.TransactOpts, _roleId, _orgId) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) RemoveRole(_roleId string, _orgId string) (*types.Transaction, error) { + return _PermInterface.Contract.RemoveRole(&_PermInterface.TransactOpts, _roleId, _orgId) +} + +// SetPermImplementation is a paid mutator transaction binding the contract method 0x511bbd9f. +// +// Solidity: function setPermImplementation(_permImplementation address) returns() +func (_PermInterface *PermInterfaceTransactor) SetPermImplementation(opts *bind.TransactOpts, _permImplementation common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "setPermImplementation", _permImplementation) +} + +// SetPermImplementation is a paid mutator transaction binding the contract method 0x511bbd9f. +// +// Solidity: function setPermImplementation(_permImplementation address) returns() +func (_PermInterface *PermInterfaceSession) SetPermImplementation(_permImplementation common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.SetPermImplementation(&_PermInterface.TransactOpts, _permImplementation) +} + +// SetPermImplementation is a paid mutator transaction binding the contract method 0x511bbd9f. +// +// Solidity: function setPermImplementation(_permImplementation address) returns() +func (_PermInterface *PermInterfaceTransactorSession) SetPermImplementation(_permImplementation common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.SetPermImplementation(&_PermInterface.TransactOpts, _permImplementation) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermInterface *PermInterfaceTransactor) SetPolicy(opts *bind.TransactOpts, _nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "setPolicy", _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermInterface *PermInterfaceSession) SetPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermInterface.Contract.SetPolicy(&_PermInterface.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// SetPolicy is a paid mutator transaction binding the contract method 0x1b610220. +// +// Solidity: function setPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) returns() +func (_PermInterface *PermInterfaceTransactorSession) SetPolicy(_nwAdminOrg string, _nwAdminRole string, _oAdminRole string) (*types.Transaction, error) { + return _PermInterface.Contract.SetPolicy(&_PermInterface.TransactOpts, _nwAdminOrg, _nwAdminRole, _oAdminRole) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0xa97914bf. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactor) StartBlacklistedAccountRecovery(opts *bind.TransactOpts, _orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "startBlacklistedAccountRecovery", _orgId, _account) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0xa97914bf. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceSession) StartBlacklistedAccountRecovery(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.StartBlacklistedAccountRecovery(&_PermInterface.TransactOpts, _orgId, _account) +} + +// StartBlacklistedAccountRecovery is a paid mutator transaction binding the contract method 0xa97914bf. +// +// Solidity: function startBlacklistedAccountRecovery(_orgId string, _account address) returns() +func (_PermInterface *PermInterfaceTransactorSession) StartBlacklistedAccountRecovery(_orgId string, _account common.Address) (*types.Transaction, error) { + return _PermInterface.Contract.StartBlacklistedAccountRecovery(&_PermInterface.TransactOpts, _orgId, _account) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x8cb58ef3. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactor) StartBlacklistedNodeRecovery(opts *bind.TransactOpts, _orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "startBlacklistedNodeRecovery", _orgId, _enodeId) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x8cb58ef3. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceSession) StartBlacklistedNodeRecovery(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.StartBlacklistedNodeRecovery(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// StartBlacklistedNodeRecovery is a paid mutator transaction binding the contract method 0x8cb58ef3. +// +// Solidity: function startBlacklistedNodeRecovery(_orgId string, _enodeId string) returns() +func (_PermInterface *PermInterfaceTransactorSession) StartBlacklistedNodeRecovery(_orgId string, _enodeId string) (*types.Transaction, error) { + return _PermInterface.Contract.StartBlacklistedNodeRecovery(&_PermInterface.TransactOpts, _orgId, _enodeId) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactor) UpdateAccountStatus(opts *bind.TransactOpts, _orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "updateAccountStatus", _orgId, _account, _action) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_PermInterface *PermInterfaceSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateAccountStatus(&_PermInterface.TransactOpts, _orgId, _account, _action) +} + +// UpdateAccountStatus is a paid mutator transaction binding the contract method 0x84b7a84a. +// +// Solidity: function updateAccountStatus(_orgId string, _account address, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactorSession) UpdateAccountStatus(_orgId string, _account common.Address, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateAccountStatus(&_PermInterface.TransactOpts, _orgId, _account, _action) +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermInterface *PermInterfaceTransactor) UpdateNetworkBootStatus(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "updateNetworkBootStatus") +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermInterface *PermInterfaceSession) UpdateNetworkBootStatus() (*types.Transaction, error) { + return _PermInterface.Contract.UpdateNetworkBootStatus(&_PermInterface.TransactOpts) +} + +// UpdateNetworkBootStatus is a paid mutator transaction binding the contract method 0x44478e79. +// +// Solidity: function updateNetworkBootStatus() returns(bool) +func (_PermInterface *PermInterfaceTransactorSession) UpdateNetworkBootStatus() (*types.Transaction, error) { + return _PermInterface.Contract.UpdateNetworkBootStatus(&_PermInterface.TransactOpts) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactor) UpdateNodeStatus(opts *bind.TransactOpts, _orgId string, _enodeId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "updateNodeStatus", _orgId, _enodeId, _action) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256) returns() +func (_PermInterface *PermInterfaceSession) UpdateNodeStatus(_orgId string, _enodeId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateNodeStatus(&_PermInterface.TransactOpts, _orgId, _enodeId, _action) +} + +// UpdateNodeStatus is a paid mutator transaction binding the contract method 0x0cc50146. +// +// Solidity: function updateNodeStatus(_orgId string, _enodeId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactorSession) UpdateNodeStatus(_orgId string, _enodeId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateNodeStatus(&_PermInterface.TransactOpts, _orgId, _enodeId, _action) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0xbb3b6e80. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactor) UpdateOrgStatus(opts *bind.TransactOpts, _orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.contract.Transact(opts, "updateOrgStatus", _orgId, _action) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0xbb3b6e80. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceSession) UpdateOrgStatus(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateOrgStatus(&_PermInterface.TransactOpts, _orgId, _action) +} + +// UpdateOrgStatus is a paid mutator transaction binding the contract method 0xbb3b6e80. +// +// Solidity: function updateOrgStatus(_orgId string, _action uint256) returns() +func (_PermInterface *PermInterfaceTransactorSession) UpdateOrgStatus(_orgId string, _action *big.Int) (*types.Transaction, error) { + return _PermInterface.Contract.UpdateOrgStatus(&_PermInterface.TransactOpts, _orgId, _action) +} diff --git a/permission/bind/permission_upgr.go b/permission/bind/permission_upgr.go new file mode 100644 index 0000000000..4762c45047 --- /dev/null +++ b/permission/bind/permission_upgr.go @@ -0,0 +1,309 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// PermUpgrABI is the input ABI used to generate the binding from. +const PermUpgrABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getPermImpl\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_proposedImpl\",\"type\":\"address\"}],\"name\":\"confirmImplChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getGuardian\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPermInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_permInterface\",\"type\":\"address\"},{\"name\":\"_permImpl\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_guardian\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" + +// PermUpgrBin is the compiled bytecode used for deploying new contracts. +const PermUpgrBin = `608060405234801561001057600080fd5b50604051602080610b2d8339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260146101000a81548160ff02191690831515021790555050610a81806100ac6000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c0100000000000000000000000000000000000000000000000000000000900480630e32cf901461007957806322bcb39a146100c3578063a75b87d214610107578063e572515c14610151578063f09a40161461019b575b600080fd5b6100816101ff565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610105600480360360208110156100d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610229565b005b61010f61053c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610159610565565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101fd600480360360408110156101b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061058f565b005b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60608060606000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc9ba6fa6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561037857600080fd5b505afa15801561038c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060808110156103b657600080fd5b8101908080516401000000008111156103ce57600080fd5b828101905060208101848111156103e457600080fd5b815185600182028301116401000000008211171561040157600080fd5b5050929190602001805164010000000081111561041d57600080fd5b8281019050602081018481111561043357600080fd5b815185600182028301116401000000008211171561045057600080fd5b5050929190602001805164010000000081111561046c57600080fd5b8281019050602081018481111561048257600080fd5b815185600182028301116401000000008211171561049f57600080fd5b50509291906020018051906020019092919050505093509350935093506104c985858585856107a4565b84600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610535600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661097d565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600260149054906101000a900460ff161515156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f63616e206265206578656375746564206f6e6c79206f6e63650000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610785600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661097d565b6001600260146101000a81548160ff0219169083151502179055505050565b8473ffffffffffffffffffffffffffffffffffffffff1663f5ad584a858585856040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b83811015610841578082015181840152602081019050610826565b50505050905090810190601f16801561086e5780820380516001836020036101000a031916815260200191505b50848103835287818151815260200191508051906020019080838360005b838110156108a757808201518184015260208101905061088c565b50505050905090810190601f1680156108d45780820380516001836020036101000a031916815260200191505b50848103825286818151815260200191508051906020019080838360005b8381101561090d5780820151818401526020810190506108f2565b50505050905090810190601f16801561093a5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561095e57600080fd5b505af1158015610972573d6000803e3d6000fd5b505050505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663511bbd9f826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015610a3a57600080fd5b505af1158015610a4e573d6000803e3d6000fd5b505050505056fea165627a7a72305820378cf538b83ea9abe4413391f6284a8f7e800144d9df63dcbba67da0f58949500029` + +// DeployPermUpgr deploys a new Ethereum contract, binding an instance of PermUpgr to it. +func DeployPermUpgr(auth *bind.TransactOpts, backend bind.ContractBackend, _guardian common.Address) (common.Address, *types.Transaction, *PermUpgr, error) { + parsed, err := abi.JSON(strings.NewReader(PermUpgrABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PermUpgrBin), backend, _guardian) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PermUpgr{PermUpgrCaller: PermUpgrCaller{contract: contract}, PermUpgrTransactor: PermUpgrTransactor{contract: contract}, PermUpgrFilterer: PermUpgrFilterer{contract: contract}}, nil +} + +// PermUpgr is an auto generated Go binding around an Ethereum contract. +type PermUpgr struct { + PermUpgrCaller // Read-only binding to the contract + PermUpgrTransactor // Write-only binding to the contract + PermUpgrFilterer // Log filterer for contract events +} + +// PermUpgrCaller is an auto generated read-only Go binding around an Ethereum contract. +type PermUpgrCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermUpgrTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PermUpgrTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermUpgrFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PermUpgrFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PermUpgrSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PermUpgrSession struct { + Contract *PermUpgr // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermUpgrCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PermUpgrCallerSession struct { + Contract *PermUpgrCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PermUpgrTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PermUpgrTransactorSession struct { + Contract *PermUpgrTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PermUpgrRaw is an auto generated low-level Go binding around an Ethereum contract. +type PermUpgrRaw struct { + Contract *PermUpgr // Generic contract binding to access the raw methods on +} + +// PermUpgrCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PermUpgrCallerRaw struct { + Contract *PermUpgrCaller // Generic read-only contract binding to access the raw methods on +} + +// PermUpgrTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PermUpgrTransactorRaw struct { + Contract *PermUpgrTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPermUpgr creates a new instance of PermUpgr, bound to a specific deployed contract. +func NewPermUpgr(address common.Address, backend bind.ContractBackend) (*PermUpgr, error) { + contract, err := bindPermUpgr(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PermUpgr{PermUpgrCaller: PermUpgrCaller{contract: contract}, PermUpgrTransactor: PermUpgrTransactor{contract: contract}, PermUpgrFilterer: PermUpgrFilterer{contract: contract}}, nil +} + +// NewPermUpgrCaller creates a new read-only instance of PermUpgr, bound to a specific deployed contract. +func NewPermUpgrCaller(address common.Address, caller bind.ContractCaller) (*PermUpgrCaller, error) { + contract, err := bindPermUpgr(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PermUpgrCaller{contract: contract}, nil +} + +// NewPermUpgrTransactor creates a new write-only instance of PermUpgr, bound to a specific deployed contract. +func NewPermUpgrTransactor(address common.Address, transactor bind.ContractTransactor) (*PermUpgrTransactor, error) { + contract, err := bindPermUpgr(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PermUpgrTransactor{contract: contract}, nil +} + +// NewPermUpgrFilterer creates a new log filterer instance of PermUpgr, bound to a specific deployed contract. +func NewPermUpgrFilterer(address common.Address, filterer bind.ContractFilterer) (*PermUpgrFilterer, error) { + contract, err := bindPermUpgr(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PermUpgrFilterer{contract: contract}, nil +} + +// bindPermUpgr binds a generic wrapper to an already deployed contract. +func bindPermUpgr(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(PermUpgrABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermUpgr *PermUpgrRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermUpgr.Contract.PermUpgrCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermUpgr *PermUpgrRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermUpgr.Contract.PermUpgrTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermUpgr *PermUpgrRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermUpgr.Contract.PermUpgrTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PermUpgr *PermUpgrCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PermUpgr.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PermUpgr *PermUpgrTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PermUpgr.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PermUpgr *PermUpgrTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PermUpgr.Contract.contract.Transact(opts, method, params...) +} + +// GetGuardian is a free data retrieval call binding the contract method 0xa75b87d2. +// +// Solidity: function getGuardian() constant returns(address) +func (_PermUpgr *PermUpgrCaller) GetGuardian(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _PermUpgr.contract.Call(opts, out, "getGuardian") + return *ret0, err +} + +// GetGuardian is a free data retrieval call binding the contract method 0xa75b87d2. +// +// Solidity: function getGuardian() constant returns(address) +func (_PermUpgr *PermUpgrSession) GetGuardian() (common.Address, error) { + return _PermUpgr.Contract.GetGuardian(&_PermUpgr.CallOpts) +} + +// GetGuardian is a free data retrieval call binding the contract method 0xa75b87d2. +// +// Solidity: function getGuardian() constant returns(address) +func (_PermUpgr *PermUpgrCallerSession) GetGuardian() (common.Address, error) { + return _PermUpgr.Contract.GetGuardian(&_PermUpgr.CallOpts) +} + +// GetPermImpl is a free data retrieval call binding the contract method 0x0e32cf90. +// +// Solidity: function getPermImpl() constant returns(address) +func (_PermUpgr *PermUpgrCaller) GetPermImpl(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _PermUpgr.contract.Call(opts, out, "getPermImpl") + return *ret0, err +} + +// GetPermImpl is a free data retrieval call binding the contract method 0x0e32cf90. +// +// Solidity: function getPermImpl() constant returns(address) +func (_PermUpgr *PermUpgrSession) GetPermImpl() (common.Address, error) { + return _PermUpgr.Contract.GetPermImpl(&_PermUpgr.CallOpts) +} + +// GetPermImpl is a free data retrieval call binding the contract method 0x0e32cf90. +// +// Solidity: function getPermImpl() constant returns(address) +func (_PermUpgr *PermUpgrCallerSession) GetPermImpl() (common.Address, error) { + return _PermUpgr.Contract.GetPermImpl(&_PermUpgr.CallOpts) +} + +// GetPermInterface is a free data retrieval call binding the contract method 0xe572515c. +// +// Solidity: function getPermInterface() constant returns(address) +func (_PermUpgr *PermUpgrCaller) GetPermInterface(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _PermUpgr.contract.Call(opts, out, "getPermInterface") + return *ret0, err +} + +// GetPermInterface is a free data retrieval call binding the contract method 0xe572515c. +// +// Solidity: function getPermInterface() constant returns(address) +func (_PermUpgr *PermUpgrSession) GetPermInterface() (common.Address, error) { + return _PermUpgr.Contract.GetPermInterface(&_PermUpgr.CallOpts) +} + +// GetPermInterface is a free data retrieval call binding the contract method 0xe572515c. +// +// Solidity: function getPermInterface() constant returns(address) +func (_PermUpgr *PermUpgrCallerSession) GetPermInterface() (common.Address, error) { + return _PermUpgr.Contract.GetPermInterface(&_PermUpgr.CallOpts) +} + +// ConfirmImplChange is a paid mutator transaction binding the contract method 0x22bcb39a. +// +// Solidity: function confirmImplChange(_proposedImpl address) returns() +func (_PermUpgr *PermUpgrTransactor) ConfirmImplChange(opts *bind.TransactOpts, _proposedImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.contract.Transact(opts, "confirmImplChange", _proposedImpl) +} + +// ConfirmImplChange is a paid mutator transaction binding the contract method 0x22bcb39a. +// +// Solidity: function confirmImplChange(_proposedImpl address) returns() +func (_PermUpgr *PermUpgrSession) ConfirmImplChange(_proposedImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.Contract.ConfirmImplChange(&_PermUpgr.TransactOpts, _proposedImpl) +} + +// ConfirmImplChange is a paid mutator transaction binding the contract method 0x22bcb39a. +// +// Solidity: function confirmImplChange(_proposedImpl address) returns() +func (_PermUpgr *PermUpgrTransactorSession) ConfirmImplChange(_proposedImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.Contract.ConfirmImplChange(&_PermUpgr.TransactOpts, _proposedImpl) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(_permInterface address, _permImpl address) returns() +func (_PermUpgr *PermUpgrTransactor) Init(opts *bind.TransactOpts, _permInterface common.Address, _permImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.contract.Transact(opts, "init", _permInterface, _permImpl) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(_permInterface address, _permImpl address) returns() +func (_PermUpgr *PermUpgrSession) Init(_permInterface common.Address, _permImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.Contract.Init(&_PermUpgr.TransactOpts, _permInterface, _permImpl) +} + +// Init is a paid mutator transaction binding the contract method 0xf09a4016. +// +// Solidity: function init(_permInterface address, _permImpl address) returns() +func (_PermUpgr *PermUpgrTransactorSession) Init(_permInterface common.Address, _permImpl common.Address) (*types.Transaction, error) { + return _PermUpgr.Contract.Init(&_PermUpgr.TransactOpts, _permInterface, _permImpl) +} diff --git a/permission/bind/roles.go b/permission/bind/roles.go new file mode 100644 index 0000000000..bb08bae9ff --- /dev/null +++ b/permission/bind/roles.go @@ -0,0 +1,688 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// RoleManagerABI is the input ABI used to generate the binding from. +const RoleManagerABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"getRoleDetails\",\"outputs\":[{\"name\":\"roleId\",\"type\":\"string\"},{\"name\":\"orgId\",\"type\":\"string\"},{\"name\":\"accessType\",\"type\":\"uint256\"},{\"name\":\"voter\",\"type\":\"bool\"},{\"name\":\"admin\",\"type\":\"bool\"},{\"name\":\"active\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_baseAccess\",\"type\":\"uint256\"},{\"name\":\"_isVoter\",\"type\":\"bool\"},{\"name\":\"_isAdmin\",\"type\":\"bool\"}],\"name\":\"addRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getNumberOfRoles\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_rIndex\",\"type\":\"uint256\"}],\"name\":\"getRoleDetailsFromIndex\",\"outputs\":[{\"name\":\"roleId\",\"type\":\"string\"},{\"name\":\"orgId\",\"type\":\"string\"},{\"name\":\"accessType\",\"type\":\"uint256\"},{\"name\":\"voter\",\"type\":\"bool\"},{\"name\":\"admin\",\"type\":\"bool\"},{\"name\":\"active\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"removeRole\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_ultParent\",\"type\":\"string\"}],\"name\":\"roleExists\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_ultParent\",\"type\":\"string\"}],\"name\":\"isAdminRole\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_roleId\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_ultParent\",\"type\":\"string\"}],\"name\":\"isVoterRole\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_roleId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_baseAccess\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_isVoter\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"_isAdmin\",\"type\":\"bool\"}],\"name\":\"RoleCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_roleId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"}]" + +// RoleManagerBin is the compiled bytecode used for deploying new contracts. +const RoleManagerBin = `608060405234801561001057600080fd5b506040516020806129598339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506128c8806100916000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063a634301211610078578063a634301214610552578063abf5739f14610620578063be322e5414610821578063deb16ba71461095c576100a5565b80631870aba3146100aa5780637b7135791461028557806387f55d31146103f9578063a451d4a814610417575b600080fd5b610176600480360360408110156100c057600080fd5b81019080803590602001906401000000008111156100dd57600080fd5b8201836020820111156100ef57600080fd5b8035906020019184600183028401116401000000008311171561011157600080fd5b90919293919293908035906020019064010000000081111561013257600080fd5b82018360208201111561014457600080fd5b8035906020019184600183028401116401000000008311171561016657600080fd5b9091929391929390505050610a97565b604051808060200180602001878152602001861515151581526020018515151515815260200184151515158152602001838103835289818151815260200191508051906020019080838360005b838110156101de5780820151818401526020810190506101c3565b50505050905090810190601f16801561020b5780820380516001836020036101000a031916815260200191505b50838103825288818151815260200191508051906020019080838360005b83811015610244578082015181840152602081019050610229565b50505050905090810190601f1680156102715780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b6103f7600480360360a081101561029b57600080fd5b81019080803590602001906401000000008111156102b857600080fd5b8201836020820111156102ca57600080fd5b803590602001918460018302840111640100000000831117156102ec57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561034f57600080fd5b82018360208201111561036157600080fd5b8035906020019184600183028401116401000000008311171561038357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803515159060200190929190803515159060200190929190505050610e9b565b005b6104016114db565b6040518082815260200191505060405180910390f35b6104436004803603602081101561042d57600080fd5b81019080803590602001909291905050506114e8565b604051808060200180602001878152602001861515151581526020018515151515815260200184151515158152602001838103835289818151815260200191508051906020019080838360005b838110156104ab578082015181840152602081019050610490565b50505050905090810190601f1680156104d85780820380516001836020036101000a031916815260200191505b50838103825288818151815260200191508051906020019080838360005b838110156105115780820151818401526020810190506104f6565b50505050905090810190601f16801561053e5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b61061e6004803603604081101561056857600080fd5b810190808035906020019064010000000081111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111640100000000831117156105b957600080fd5b9091929391929390803590602001906401000000008111156105da57600080fd5b8201836020820111156105ec57600080fd5b8035906020019184600183028401116401000000008311171561060e57600080fd5b9091929391929390505050611729565b005b6108076004803603606081101561063657600080fd5b810190808035906020019064010000000081111561065357600080fd5b82018360208201111561066557600080fd5b8035906020019184600183028401116401000000008311171561068757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156106ea57600080fd5b8201836020820111156106fc57600080fd5b8035906020019184600183028401116401000000008311171561071e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561078157600080fd5b82018360208201111561079357600080fd5b803590602001918460018302840111640100000000831117156107b557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611b08565b604051808215151515815260200191505060405180910390f35b6109426004803603606081101561083757600080fd5b810190808035906020019064010000000081111561085457600080fd5b82018360208201111561086657600080fd5b8035906020019184600183028401116401000000008311171561088857600080fd5b9091929391929390803590602001906401000000008111156108a957600080fd5b8201836020820111156108bb57600080fd5b803590602001918460018302840111640100000000831117156108dd57600080fd5b9091929391929390803590602001906401000000008111156108fe57600080fd5b82018360208201111561091057600080fd5b8035906020019184600183028401116401000000008311171561093257600080fd5b9091929391929390505050611dc6565b604051808215151515815260200191505060405180910390f35b610a7d6004803603606081101561097257600080fd5b810190808035906020019064010000000081111561098f57600080fd5b8201836020820111156109a157600080fd5b803590602001918460018302840111640100000000831117156109c357600080fd5b9091929391929390803590602001906401000000008111156109e457600080fd5b8201836020820111156109f657600080fd5b80359060200191846001830284011164010000000083111715610a1857600080fd5b909192939192939080359060200190640100000000811115610a3957600080fd5b820183602082011115610a4b57600080fd5b80359060200191846001830284011164010000000083111715610a6d57600080fd5b9091929391929390505050612252565b604051808215151515815260200191505060405180910390f35b606080600080600080610b438a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506020604051908101604052806000815250611b08565b1515610bc757898960008060008085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509450909192939450602060405190810160405280600081525093929190839350955095509550955095509550610e8e565b6000610c5b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b9050600181815481101515610c6c57fe5b9060005260206000209060040201600001600182815481101515610c8c57fe5b9060005260206000209060040201600101600183815481101515610cac57fe5b906000526020600020906004020160020154600184815481101515610ccd57fe5b906000526020600020906004020160030160009054906101000a900460ff16600185815481101515610cfb57fe5b906000526020600020906004020160030160019054906101000a900460ff16600186815481101515610d2957fe5b906000526020600020906004020160030160029054906101000a900460ff16858054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ddd5780601f10610db257610100808354040283529160200191610ddd565b820191906000526020600020905b815481529060010190602001808311610dc057829003601f168201915b50505050509550848054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e795780601f10610e4e57610100808354040283529160200191610e79565b820191906000526020600020905b815481529060010190602001808311610e5c57829003601f168201915b50505050509450965096509650965096509650505b9499939850945094509450565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610f1e57600080fd5b505afa158015610f32573d6000803e3d6000fd5b505050506040513d6020811015610f4857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561104a57808201518184015260208101905061102f565b50505050905090810190601f1680156110775780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156110b0578082015181840152602081019050611095565b50505050905090810190601f1680156110dd5780820380516001836020036101000a031916815260200191505b509450505050506040516020818303038152906040528051906020012081526020019081526020016000205414151561117e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f726f6c652065786973747320666f7220746865206f726700000000000000000081525060200191505060405180910390fd5b600360008154809291906001019190505550600354600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b838110156111e05780820151818401526020810190506111c5565b50505050905090810190601f16801561120d5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561124657808201518184015260208101905061122b565b50505050905090810190601f1680156112735780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160c06040519081016040528087815260200186815260200185815260200184151581526020018315158152602001600115158152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000190805190602001906113209291906127f7565b50602082015181600101908051906020019061133d9291906127f7565b506040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548160ff02191690831515021790555060a08201518160030160026101000a81548160ff0219169083151502179055505050507fefa5bc1bedbee25b04b00855c15a0c180ecb4a2440d4d08296e49561655e2b1c85858585856040518080602001806020018681526020018515151515815260200184151515158152602001838103835288818151815260200191508051906020019080838360005b8381101561142f578082015181840152602081019050611414565b50505050905090810190601f16801561145c5780820380516001836020036101000a031916815260200191505b50838103825287818151815260200191508051906020019080838360005b8381101561149557808201518184015260208101905061147a565b50505050905090810190601f1680156114c25780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15050505050565b6000600180549050905090565b60608060008060008060018781548110151561150057fe5b906000526020600020906004020160000160018881548110151561152057fe5b906000526020600020906004020160010160018981548110151561154057fe5b90600052602060002090600402016002015460018a81548110151561156157fe5b906000526020600020906004020160030160009054906101000a900460ff1660018b81548110151561158f57fe5b906000526020600020906004020160030160019054906101000a900460ff1660018c8154811015156115bd57fe5b906000526020600020906004020160030160029054906101000a900460ff16858054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116715780601f1061164657610100808354040283529160200191611671565b820191906000526020600020905b81548152906001019060200180831161165457829003601f168201915b50505050509550848054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561170d5780601f106116e25761010080835404028352916020019161170d565b820191906000526020600020905b8154815290600101906020018083116116f057829003601f168201915b5050505050945095509550955095509550955091939550919395565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156117ac57600080fd5b505afa1580156117c0573d6000803e3d6000fd5b505050506040513d60208110156117d657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611889576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600060026000868686866040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050604051602081830303815290604052805190602001208152602001908152602001600020541415151561199b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f726f6c6520646f6573206e6f742065786973740000000000000000000000000081525060200191505060405180910390fd5b6000611a2f85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90506000600182815481101515611a4257fe5b906000526020600020906004020160030160026101000a81548160ff0219169083151502179055507f1196059dd83524bf989fd94bb65808c09dbea2ab791fb6bfa87a0e0aa64b2ea6858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000806000600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611b5a578082015181840152602081019050611b3f565b50505050905090810190601f168015611b875780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611bc0578082015181840152602081019050611ba5565b50505050905090810190601f168015611bed5780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002054141515611c6257611c2a85856126de565b9050600181815481101515611c3b57fe5b906000526020600020906004020160030160029054906101000a900460ff16915050611dbf565b6000600260008786604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611cb1578082015181840152602081019050611c96565b50505050905090810190601f168015611cde5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611d17578082015181840152602081019050611cfc565b50505050905090810190601f168015611d445780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002054141515611db957611d8185846126de565b9050600181815481101515611d9257fe5b906000526020600020906004020160030160029054906101000a900460ff16915050611dbf565b60009150505b9392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611e4b57600080fd5b505afa158015611e5f573d6000803e3d6000fd5b505050506040513d6020811015611e7557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611fff87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b08565b151561200e5760009050612248565b600080600260008a8a8a8a6040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f82011690508083019250505096505050505050506040516020818303038152906040528051906020012081526020019081526020016000205414151561214b5761214488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90506121e0565b6121dd88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90505b6001818154811015156121ef57fe5b906000526020600020906004020160030160029054906101000a900460ff168015612244575060018181548110151561222457fe5b906000526020600020906004020160030160019054906101000a900460ff165b9150505b9695505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156122d757600080fd5b505afa1580156122eb573d6000803e3d6000fd5b505050506040513d602081101561230157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b61248b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b08565b151561249a57600090506126d4565b600080600260008a8a8a8a6040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050604051602081830303815290604052805190602001208152602001908152602001600020541415156125d7576125d088888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b905061266c565b61266988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90505b60018181548110151561267b57fe5b906000526020600020906004020160030160029054906101000a900460ff1680156126d057506001818154811015156126b057fe5b906000526020600020906004020160030160009054906101000a900460ff165b9150505b9695505050505050565b60006001600260008585604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561272f578082015181840152602081019050612714565b50505050905090810190601f16801561275c5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561279557808201518184015260208101905061277a565b50505050905090810190601f1680156127c25780820380516001836020036101000a031916815260200191505b509450505050506040516020818303038152906040528051906020012081526020019081526020016000205403905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061283857805160ff1916838001178555612866565b82800160010185558215612866579182015b8281111561286557825182559160200191906001019061284a565b5b5090506128739190612877565b5090565b61289991905b8082111561289557600081600090555060010161287d565b5090565b9056fea165627a7a7230582006ce3e54be3a54da4e284827f5291f19d7bc4a8fa63cfe3ce43f1e50c45ba2f00029` + +// DeployRoleManager deploys a new Ethereum contract, binding an instance of RoleManager to it. +func DeployRoleManager(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address) (common.Address, *types.Transaction, *RoleManager, error) { + parsed, err := abi.JSON(strings.NewReader(RoleManagerABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(RoleManagerBin), backend, _permUpgradable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RoleManager{RoleManagerCaller: RoleManagerCaller{contract: contract}, RoleManagerTransactor: RoleManagerTransactor{contract: contract}, RoleManagerFilterer: RoleManagerFilterer{contract: contract}}, nil +} + +// RoleManager is an auto generated Go binding around an Ethereum contract. +type RoleManager struct { + RoleManagerCaller // Read-only binding to the contract + RoleManagerTransactor // Write-only binding to the contract + RoleManagerFilterer // Log filterer for contract events +} + +// RoleManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type RoleManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RoleManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RoleManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RoleManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RoleManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RoleManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RoleManagerSession struct { + Contract *RoleManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RoleManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RoleManagerCallerSession struct { + Contract *RoleManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RoleManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RoleManagerTransactorSession struct { + Contract *RoleManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RoleManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type RoleManagerRaw struct { + Contract *RoleManager // Generic contract binding to access the raw methods on +} + +// RoleManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RoleManagerCallerRaw struct { + Contract *RoleManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// RoleManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RoleManagerTransactorRaw struct { + Contract *RoleManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRoleManager creates a new instance of RoleManager, bound to a specific deployed contract. +func NewRoleManager(address common.Address, backend bind.ContractBackend) (*RoleManager, error) { + contract, err := bindRoleManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RoleManager{RoleManagerCaller: RoleManagerCaller{contract: contract}, RoleManagerTransactor: RoleManagerTransactor{contract: contract}, RoleManagerFilterer: RoleManagerFilterer{contract: contract}}, nil +} + +// NewRoleManagerCaller creates a new read-only instance of RoleManager, bound to a specific deployed contract. +func NewRoleManagerCaller(address common.Address, caller bind.ContractCaller) (*RoleManagerCaller, error) { + contract, err := bindRoleManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RoleManagerCaller{contract: contract}, nil +} + +// NewRoleManagerTransactor creates a new write-only instance of RoleManager, bound to a specific deployed contract. +func NewRoleManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*RoleManagerTransactor, error) { + contract, err := bindRoleManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RoleManagerTransactor{contract: contract}, nil +} + +// NewRoleManagerFilterer creates a new log filterer instance of RoleManager, bound to a specific deployed contract. +func NewRoleManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*RoleManagerFilterer, error) { + contract, err := bindRoleManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RoleManagerFilterer{contract: contract}, nil +} + +// bindRoleManager binds a generic wrapper to an already deployed contract. +func bindRoleManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(RoleManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RoleManager *RoleManagerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _RoleManager.Contract.RoleManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RoleManager *RoleManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RoleManager.Contract.RoleManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RoleManager *RoleManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RoleManager.Contract.RoleManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RoleManager *RoleManagerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _RoleManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RoleManager *RoleManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RoleManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RoleManager *RoleManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RoleManager.Contract.contract.Transact(opts, method, params...) +} + +// GetNumberOfRoles is a free data retrieval call binding the contract method 0x87f55d31. +// +// Solidity: function getNumberOfRoles() constant returns(uint256) +func (_RoleManager *RoleManagerCaller) GetNumberOfRoles(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _RoleManager.contract.Call(opts, out, "getNumberOfRoles") + return *ret0, err +} + +// GetNumberOfRoles is a free data retrieval call binding the contract method 0x87f55d31. +// +// Solidity: function getNumberOfRoles() constant returns(uint256) +func (_RoleManager *RoleManagerSession) GetNumberOfRoles() (*big.Int, error) { + return _RoleManager.Contract.GetNumberOfRoles(&_RoleManager.CallOpts) +} + +// GetNumberOfRoles is a free data retrieval call binding the contract method 0x87f55d31. +// +// Solidity: function getNumberOfRoles() constant returns(uint256) +func (_RoleManager *RoleManagerCallerSession) GetNumberOfRoles() (*big.Int, error) { + return _RoleManager.Contract.GetNumberOfRoles(&_RoleManager.CallOpts) +} + +// GetRoleDetails is a free data retrieval call binding the contract method 0x1870aba3. +// +// Solidity: function getRoleDetails(_roleId string, _orgId string) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerCaller) GetRoleDetails(opts *bind.CallOpts, _roleId string, _orgId string) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + ret := new(struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool + }) + out := ret + err := _RoleManager.contract.Call(opts, out, "getRoleDetails", _roleId, _orgId) + return *ret, err +} + +// GetRoleDetails is a free data retrieval call binding the contract method 0x1870aba3. +// +// Solidity: function getRoleDetails(_roleId string, _orgId string) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerSession) GetRoleDetails(_roleId string, _orgId string) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + return _RoleManager.Contract.GetRoleDetails(&_RoleManager.CallOpts, _roleId, _orgId) +} + +// GetRoleDetails is a free data retrieval call binding the contract method 0x1870aba3. +// +// Solidity: function getRoleDetails(_roleId string, _orgId string) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerCallerSession) GetRoleDetails(_roleId string, _orgId string) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + return _RoleManager.Contract.GetRoleDetails(&_RoleManager.CallOpts, _roleId, _orgId) +} + +// GetRoleDetailsFromIndex is a free data retrieval call binding the contract method 0xa451d4a8. +// +// Solidity: function getRoleDetailsFromIndex(_rIndex uint256) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerCaller) GetRoleDetailsFromIndex(opts *bind.CallOpts, _rIndex *big.Int) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + ret := new(struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool + }) + out := ret + err := _RoleManager.contract.Call(opts, out, "getRoleDetailsFromIndex", _rIndex) + return *ret, err +} + +// GetRoleDetailsFromIndex is a free data retrieval call binding the contract method 0xa451d4a8. +// +// Solidity: function getRoleDetailsFromIndex(_rIndex uint256) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerSession) GetRoleDetailsFromIndex(_rIndex *big.Int) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + return _RoleManager.Contract.GetRoleDetailsFromIndex(&_RoleManager.CallOpts, _rIndex) +} + +// GetRoleDetailsFromIndex is a free data retrieval call binding the contract method 0xa451d4a8. +// +// Solidity: function getRoleDetailsFromIndex(_rIndex uint256) constant returns(roleId string, orgId string, accessType uint256, voter bool, admin bool, active bool) +func (_RoleManager *RoleManagerCallerSession) GetRoleDetailsFromIndex(_rIndex *big.Int) (struct { + RoleId string + OrgId string + AccessType *big.Int + Voter bool + Admin bool + Active bool +}, error) { + return _RoleManager.Contract.GetRoleDetailsFromIndex(&_RoleManager.CallOpts, _rIndex) +} + +// IsAdminRole is a free data retrieval call binding the contract method 0xbe322e54. +// +// Solidity: function isAdminRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCaller) IsAdminRole(opts *bind.CallOpts, _roleId string, _orgId string, _ultParent string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _RoleManager.contract.Call(opts, out, "isAdminRole", _roleId, _orgId, _ultParent) + return *ret0, err +} + +// IsAdminRole is a free data retrieval call binding the contract method 0xbe322e54. +// +// Solidity: function isAdminRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerSession) IsAdminRole(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.IsAdminRole(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// IsAdminRole is a free data retrieval call binding the contract method 0xbe322e54. +// +// Solidity: function isAdminRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCallerSession) IsAdminRole(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.IsAdminRole(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// IsVoterRole is a free data retrieval call binding the contract method 0xdeb16ba7. +// +// Solidity: function isVoterRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCaller) IsVoterRole(opts *bind.CallOpts, _roleId string, _orgId string, _ultParent string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _RoleManager.contract.Call(opts, out, "isVoterRole", _roleId, _orgId, _ultParent) + return *ret0, err +} + +// IsVoterRole is a free data retrieval call binding the contract method 0xdeb16ba7. +// +// Solidity: function isVoterRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerSession) IsVoterRole(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.IsVoterRole(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// IsVoterRole is a free data retrieval call binding the contract method 0xdeb16ba7. +// +// Solidity: function isVoterRole(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCallerSession) IsVoterRole(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.IsVoterRole(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// RoleExists is a free data retrieval call binding the contract method 0xabf5739f. +// +// Solidity: function roleExists(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCaller) RoleExists(opts *bind.CallOpts, _roleId string, _orgId string, _ultParent string) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _RoleManager.contract.Call(opts, out, "roleExists", _roleId, _orgId, _ultParent) + return *ret0, err +} + +// RoleExists is a free data retrieval call binding the contract method 0xabf5739f. +// +// Solidity: function roleExists(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerSession) RoleExists(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.RoleExists(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// RoleExists is a free data retrieval call binding the contract method 0xabf5739f. +// +// Solidity: function roleExists(_roleId string, _orgId string, _ultParent string) constant returns(bool) +func (_RoleManager *RoleManagerCallerSession) RoleExists(_roleId string, _orgId string, _ultParent string) (bool, error) { + return _RoleManager.Contract.RoleExists(&_RoleManager.CallOpts, _roleId, _orgId, _ultParent) +} + +// AddRole is a paid mutator transaction binding the contract method 0x7b713579. +// +// Solidity: function addRole(_roleId string, _orgId string, _baseAccess uint256, _isVoter bool, _isAdmin bool) returns() +func (_RoleManager *RoleManagerTransactor) AddRole(opts *bind.TransactOpts, _roleId string, _orgId string, _baseAccess *big.Int, _isVoter bool, _isAdmin bool) (*types.Transaction, error) { + return _RoleManager.contract.Transact(opts, "addRole", _roleId, _orgId, _baseAccess, _isVoter, _isAdmin) +} + +// AddRole is a paid mutator transaction binding the contract method 0x7b713579. +// +// Solidity: function addRole(_roleId string, _orgId string, _baseAccess uint256, _isVoter bool, _isAdmin bool) returns() +func (_RoleManager *RoleManagerSession) AddRole(_roleId string, _orgId string, _baseAccess *big.Int, _isVoter bool, _isAdmin bool) (*types.Transaction, error) { + return _RoleManager.Contract.AddRole(&_RoleManager.TransactOpts, _roleId, _orgId, _baseAccess, _isVoter, _isAdmin) +} + +// AddRole is a paid mutator transaction binding the contract method 0x7b713579. +// +// Solidity: function addRole(_roleId string, _orgId string, _baseAccess uint256, _isVoter bool, _isAdmin bool) returns() +func (_RoleManager *RoleManagerTransactorSession) AddRole(_roleId string, _orgId string, _baseAccess *big.Int, _isVoter bool, _isAdmin bool) (*types.Transaction, error) { + return _RoleManager.Contract.AddRole(&_RoleManager.TransactOpts, _roleId, _orgId, _baseAccess, _isVoter, _isAdmin) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_RoleManager *RoleManagerTransactor) RemoveRole(opts *bind.TransactOpts, _roleId string, _orgId string) (*types.Transaction, error) { + return _RoleManager.contract.Transact(opts, "removeRole", _roleId, _orgId) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_RoleManager *RoleManagerSession) RemoveRole(_roleId string, _orgId string) (*types.Transaction, error) { + return _RoleManager.Contract.RemoveRole(&_RoleManager.TransactOpts, _roleId, _orgId) +} + +// RemoveRole is a paid mutator transaction binding the contract method 0xa6343012. +// +// Solidity: function removeRole(_roleId string, _orgId string) returns() +func (_RoleManager *RoleManagerTransactorSession) RemoveRole(_roleId string, _orgId string) (*types.Transaction, error) { + return _RoleManager.Contract.RemoveRole(&_RoleManager.TransactOpts, _roleId, _orgId) +} + +// RoleManagerRoleCreatedIterator is returned from FilterRoleCreated and is used to iterate over the raw logs and unpacked data for RoleCreated events raised by the RoleManager contract. +type RoleManagerRoleCreatedIterator struct { + Event *RoleManagerRoleCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RoleManagerRoleCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RoleManagerRoleCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RoleManagerRoleCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RoleManagerRoleCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RoleManagerRoleCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RoleManagerRoleCreated represents a RoleCreated event raised by the RoleManager contract. +type RoleManagerRoleCreated struct { + RoleId string + OrgId string + BaseAccess *big.Int + IsVoter bool + IsAdmin bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleCreated is a free log retrieval operation binding the contract event 0xefa5bc1bedbee25b04b00855c15a0c180ecb4a2440d4d08296e49561655e2b1c. +// +// Solidity: e RoleCreated(_roleId string, _orgId string, _baseAccess uint256, _isVoter bool, _isAdmin bool) +func (_RoleManager *RoleManagerFilterer) FilterRoleCreated(opts *bind.FilterOpts) (*RoleManagerRoleCreatedIterator, error) { + + logs, sub, err := _RoleManager.contract.FilterLogs(opts, "RoleCreated") + if err != nil { + return nil, err + } + return &RoleManagerRoleCreatedIterator{contract: _RoleManager.contract, event: "RoleCreated", logs: logs, sub: sub}, nil +} + +// WatchRoleCreated is a free log subscription operation binding the contract event 0xefa5bc1bedbee25b04b00855c15a0c180ecb4a2440d4d08296e49561655e2b1c. +// +// Solidity: e RoleCreated(_roleId string, _orgId string, _baseAccess uint256, _isVoter bool, _isAdmin bool) +func (_RoleManager *RoleManagerFilterer) WatchRoleCreated(opts *bind.WatchOpts, sink chan<- *RoleManagerRoleCreated) (event.Subscription, error) { + + logs, sub, err := _RoleManager.contract.WatchLogs(opts, "RoleCreated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RoleManagerRoleCreated) + if err := _RoleManager.contract.UnpackLog(event, "RoleCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// RoleManagerRoleRevokedIterator is returned from FilterRoleRevoked and is used to iterate over the raw logs and unpacked data for RoleRevoked events raised by the RoleManager contract. +type RoleManagerRoleRevokedIterator struct { + Event *RoleManagerRoleRevoked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RoleManagerRoleRevokedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RoleManagerRoleRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RoleManagerRoleRevoked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RoleManagerRoleRevokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RoleManagerRoleRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RoleManagerRoleRevoked represents a RoleRevoked event raised by the RoleManager contract. +type RoleManagerRoleRevoked struct { + RoleId string + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleRevoked is a free log retrieval operation binding the contract event 0x1196059dd83524bf989fd94bb65808c09dbea2ab791fb6bfa87a0e0aa64b2ea6. +// +// Solidity: e RoleRevoked(_roleId string, _orgId string) +func (_RoleManager *RoleManagerFilterer) FilterRoleRevoked(opts *bind.FilterOpts) (*RoleManagerRoleRevokedIterator, error) { + + logs, sub, err := _RoleManager.contract.FilterLogs(opts, "RoleRevoked") + if err != nil { + return nil, err + } + return &RoleManagerRoleRevokedIterator{contract: _RoleManager.contract, event: "RoleRevoked", logs: logs, sub: sub}, nil +} + +// WatchRoleRevoked is a free log subscription operation binding the contract event 0x1196059dd83524bf989fd94bb65808c09dbea2ab791fb6bfa87a0e0aa64b2ea6. +// +// Solidity: e RoleRevoked(_roleId string, _orgId string) +func (_RoleManager *RoleManagerFilterer) WatchRoleRevoked(opts *bind.WatchOpts, sink chan<- *RoleManagerRoleRevoked) (event.Subscription, error) { + + logs, sub, err := _RoleManager.contract.WatchLogs(opts, "RoleRevoked") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RoleManagerRoleRevoked) + if err := _RoleManager.contract.UnpackLog(event, "RoleRevoked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/bind/voter.go b/permission/bind/voter.go new file mode 100644 index 0000000000..d328188c26 --- /dev/null +++ b/permission/bind/voter.go @@ -0,0 +1,797 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package permission + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = abi.U256 + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// VoterManagerABI is the input ABI used to generate the binding from. +const VoterManagerABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"getPendingOpDetails\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_vAccount\",\"type\":\"address\"}],\"name\":\"addVoter\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_vAccount\",\"type\":\"address\"}],\"name\":\"deleteVoter\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_authOrg\",\"type\":\"string\"},{\"name\":\"_vAccount\",\"type\":\"address\"},{\"name\":\"_pendingOp\",\"type\":\"uint256\"}],\"name\":\"processVote\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_authOrg\",\"type\":\"string\"},{\"name\":\"_orgId\",\"type\":\"string\"},{\"name\":\"_enodeId\",\"type\":\"string\"},{\"name\":\"_account\",\"type\":\"address\"},{\"name\":\"_pendingOp\",\"type\":\"uint256\"}],\"name\":\"addVotingItem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_permUpgradable\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_vAccount\",\"type\":\"address\"}],\"name\":\"VoterAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_vAccount\",\"type\":\"address\"}],\"name\":\"VoterDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"VotingItemAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_orgId\",\"type\":\"string\"}],\"name\":\"VoteProcessed\",\"type\":\"event\"}]" + +// VoterManagerBin is the compiled bytecode used for deploying new contracts. +const VoterManagerBin = `6080604052600060035534801561001557600080fd5b506040516020806129498339810180604052602081101561003557600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506128b3806100966000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c010000000000000000000000000000000000000000000000000000000090048063014e6acc146100795780635607395b1461021157806359cbd6fe146102aa578063b021386414610343578063e98ac22d146103fe575b600080fd5b6100f06004803603602081101561008f57600080fd5b81019080803590602001906401000000008111156100ac57600080fd5b8201836020820111156100be57600080fd5b803590602001918460018302840111640100000000831117156100e057600080fd5b909192939192939050505061054b565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b8381101561016c578082015181840152602081019050610151565b50505050905090810190601f1680156101995780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b838110156101d25780820151818401526020810190506101b7565b50505050905090810190601f1680156101ff5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b6102a86004803603604081101561022757600080fd5b810190808035906020019064010000000081111561024457600080fd5b82018360208201111561025657600080fd5b8035906020019184600183028401116401000000008311171561027857600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108fa565b005b610341600480360360408110156102c057600080fd5b81019080803590602001906401000000008111156102dd57600080fd5b8201836020820111156102ef57600080fd5b8035906020019184600183028401116401000000008311171561031157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611336565b005b6103e46004803603606081101561035957600080fd5b810190808035906020019064010000000081111561037657600080fd5b82018360208201111561038857600080fd5b803590602001918460018302840111640100000000831117156103aa57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611728565b604051808215151515815260200191505060405180910390f35b610549600480360360a081101561041457600080fd5b810190808035906020019064010000000081111561043157600080fd5b82018360208201111561044357600080fd5b8035906020019184600183028401116401000000008311171561046557600080fd5b90919293919293908035906020019064010000000081111561048657600080fd5b82018360208201111561049857600080fd5b803590602001918460018302840111640100000000831117156104ba57600080fd5b9091929391929390803590602001906401000000008111156104db57600080fd5b8201836020820111156104ed57600080fd5b8035906020019184600183028401116401000000008311171561050f57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e0a565b005b6060806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156105d457600080fd5b505afa1580156105e8573d6000803e3d6000fd5b505050506040513d60208110156105fe57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600061070087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b905060018181548110151561071157fe5b90600052602060002090600b020160040160000160018281548110151561073457fe5b90600052602060002090600b020160040160010160018381548110151561075757fe5b90600052602060002090600b020160040160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018481548110151561079b57fe5b90600052602060002090600b020160040160030154838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108455780601f1061081a57610100808354040283529160200191610845565b820191906000526020600020905b81548152906001019060200180831161082857829003601f168201915b50505050509350828054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108e15780601f106108b6576101008083540402835291602001916108e1565b820191906000526020600020905b8154815290600101906020018083116108c457829003601f168201915b5050505050925094509450945094505092959194509250565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561097d57600080fd5b505afa158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600060026000858560405160200180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050604051602081830303815290604052805190602001208152602001908152602001600020541415610e815760036000815480929190600101919050555060035460026000858560405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600060018054809190600101610b5c919061258c565b90508383600183815481101515610b6f57fe5b90600052602060002090600b02016000019190610b8d9291906125be565b5060018082815481101515610b9e57fe5b90600052602060002090600b02016001018190555060018082815481101515610bc357fe5b90600052602060002090600b0201600201819055506000600182815481101515610be957fe5b90600052602060002090600b0201600301819055506020604051908101604052806000815250600182815481101515610c1e57fe5b90600052602060002090600b02016004016000019080519060200190610c4592919061263e565b506020604051908101604052806000815250600182815481101515610c6657fe5b90600052602060002090600b02016004016001019080519060200190610c8d92919061263e565b506000600182815481101515610c9f57fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600182815481101515610d0257fe5b90600052602060002090600b020160040160030181905550600181815481101515610d2957fe5b90600052602060002090600b020160010154600182815481101515610d4a57fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600181815481101515610dab57fe5b90600052602060002090600b020160080160408051908101604052808473ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525090806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050505061129a565b6000610ed084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b90506000600182815481101515610ee357fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156110fe57600181815481101515610f4757fe5b90600052602060002090600b020160010160008154809291906001019190505550600181815481101515610f7757fe5b90600052602060002090600b020160010154600182815481101515610f9857fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600181815481101515610ff957fe5b90600052602060002090600b020160080160408051908101604052808473ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525090806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050506001818154811015156110d857fe5b90600052602060002090600b020160020160008154809291906001019190505550611298565b600061114e85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846123fe565b90506001151560018381548110151561116357fe5b90600052602060002090600b02016008018281548110151561118157fe5b9060005260206000200160000160149054906101000a900460ff16151514151515611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f616c7265616479206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b6001808381548110151561122457fe5b90600052602060002090600b02016008018281548110151561124257fe5b9060005260206000200160000160146101000a81548160ff02191690831515021790555060018281548110151561127557fe5b90600052602060002090600b020160020160008154809291906001019190505550505b505b7f424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d3457483838360405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a1505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156113b957600080fd5b505afa1580156113cd573d6000803e3d6000fd5b505050506040513d60208110156113e357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081600115156114ea8383612475565b1515141515611561576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6d757374206265206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b60006115b086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b9050600061160287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050866123fe565b905060018281548110151561161357fe5b90600052602060002090600b02016002016000815480929190600190039190505550600060018381548110151561164657fe5b90600052602060002090600b02016008018281548110151561166457fe5b9060005260206000200160000160146101000a81548160ff0219169083151502179055507f654cd85d9b2abaf3affef0a047625d088e6e4d0448935c9b5016b5f5aa0ca3b687878760405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a150505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156117ad57600080fd5b505afa1580156117c1573d6000803e3d6000fd5b505050506040513d60208110156117d757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505083600115156118de8383612475565b1515141515611955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6d757374206265206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b600115156119a788888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086612554565b1515141515611a1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000611a6d88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b905060011515600182815481101515611a8257fe5b90600052602060002090600b0201600a01600083815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514151515611b67576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f63616e6e6f7420646f75626c6520766f7465000000000000000000000000000081525060200191505060405180910390fd5b600181815481101515611b7657fe5b90600052602060002090600b02016003016000815480929190600101919050555060018082815481101515611ba757fe5b90600052602060002090600b0201600a01600083815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f87999b54e45aa02834a1265e356d7bcdceb72b8cbb4396ebaeba32a103b43508888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a16002600182815481101515611c9157fe5b90600052602060002090600b020160020154811515611cac57fe5b04600182815481101515611cbc57fe5b90600052602060002090600b0201600301541115611dfa576020604051908101604052806000815250600182815481101515611cf457fe5b90600052602060002090600b02016004016000019080519060200190611d1b92919061263e565b506020604051908101604052806000815250600182815481101515611d3c57fe5b90600052602060002090600b02016004016001019080519060200190611d6392919061263e565b506000600182815481101515611d7557fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600182815481101515611dd857fe5b90600052602060002090600b0201600401600301819055506001935050611e00565b60009350505b5050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611e8d57600080fd5b505afa158015611ea1573d6000803e3d6000fd5b505050506040513d6020811015611eb757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611fb988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000612554565b1515612010576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806128546034913960400191505060405180910390fd5b600061205f89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b9050868660018381548110151561207257fe5b90600052602060002090600b020160040160000191906120939291906125be565b5084846001838154811015156120a557fe5b90600052602060002090600b020160040160010191906120c69291906125be565b50826001828154811015156120d757fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160018281548110151561213957fe5b90600052602060002090600b02016004016003018190555060008090505b60018281548110151561216657fe5b90600052602060002090600b0201600801805490508110156122be5760018281548110151561219157fe5b90600052602060002090600b0201600801818154811015156121af57fe5b9060005260206000200160000160149054906101000a900460ff16156122b15760006001838154811015156121e057fe5b90600052602060002090600b0201600a016000848152602001908152602001600020600060018581548110151561221357fe5b90600052602060002090600b02016008018481548110151561223157fe5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b8080600101915050612157565b5060006001828154811015156122d057fe5b90600052602060002090600b0201600301819055507f5bfaebb5931145594f63236d2a59314c4dc6035b65d0ca4cee9c7298e2f06ca3898960405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a1505050505050505050565b6000600160026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561239f578082015181840152602081019050612384565b50505050905090810190601f1680156123cc5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b60008061240a84612353565b90506001808281548110151561241c57fe5b90600052602060002090600b020160090160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540391505092915050565b60008061248184612353565b9050600060018281548110151561249457fe5b90600052602060002090600b020160090160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156124f357600091505061254e565b60006124ff85856123fe565b905060018281548110151561251057fe5b90600052602060002090600b02016008018181548110151561252e57fe5b9060005260206000200160000160149054906101000a900460ff16925050505b92915050565b600081600161256285612353565b81548110151561256e57fe5b90600052602060002090600b02016004016003015414905092915050565b8154818355818111156125b957600b0281600b0283600052602060002091820191016125b891906126be565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106125ff57803560ff191683800117855561262d565b8280016001018555821561262d579182015b8281111561262c578235825591602001919060010190612611565b5b50905061263a919061276b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061267f57805160ff19168380011785556126ad565b828001600101855582156126ad579182015b828111156126ac578251825591602001919060010190612691565b5b5090506126ba919061276b565b5090565b61276891905b8082111561276457600080820160006126dd9190612790565b600182016000905560028201600090556003820160009055600482016000808201600061270a9190612790565b60018201600061271a9190612790565b6002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160009055505060088201600061275b91906127d8565b50600b016126c4565b5090565b90565b61278d91905b80821115612789576000816000905550600101612771565b5090565b90565b50805460018160011615610100020316600290046000825580601f106127b657506127d5565b601f0160209004906000526020600020908101906127d4919061276b565b5b50565b50805460008255906000526020600020908101906127f691906127f9565b50565b61285091905b8082111561284c57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff0219169055506001016127ff565b5090565b9056fe6974656d732070656e64696e6720666f7220617070726f76616c2e206e6577206974656d2063616e6e6f74206265206164646564a165627a7a723058209bcb200dffe1c7dbbf4661d7181f768f85d4dda30f18c49d34e48846e15a15430029` + +// DeployVoterManager deploys a new Ethereum contract, binding an instance of VoterManager to it. +func DeployVoterManager(auth *bind.TransactOpts, backend bind.ContractBackend, _permUpgradable common.Address) (common.Address, *types.Transaction, *VoterManager, error) { + parsed, err := abi.JSON(strings.NewReader(VoterManagerABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(VoterManagerBin), backend, _permUpgradable) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VoterManager{VoterManagerCaller: VoterManagerCaller{contract: contract}, VoterManagerTransactor: VoterManagerTransactor{contract: contract}, VoterManagerFilterer: VoterManagerFilterer{contract: contract}}, nil +} + +// VoterManager is an auto generated Go binding around an Ethereum contract. +type VoterManager struct { + VoterManagerCaller // Read-only binding to the contract + VoterManagerTransactor // Write-only binding to the contract + VoterManagerFilterer // Log filterer for contract events +} + +// VoterManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type VoterManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VoterManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type VoterManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VoterManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type VoterManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VoterManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type VoterManagerSession struct { + Contract *VoterManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// VoterManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type VoterManagerCallerSession struct { + Contract *VoterManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// VoterManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type VoterManagerTransactorSession struct { + Contract *VoterManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// VoterManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type VoterManagerRaw struct { + Contract *VoterManager // Generic contract binding to access the raw methods on +} + +// VoterManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type VoterManagerCallerRaw struct { + Contract *VoterManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// VoterManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type VoterManagerTransactorRaw struct { + Contract *VoterManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewVoterManager creates a new instance of VoterManager, bound to a specific deployed contract. +func NewVoterManager(address common.Address, backend bind.ContractBackend) (*VoterManager, error) { + contract, err := bindVoterManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VoterManager{VoterManagerCaller: VoterManagerCaller{contract: contract}, VoterManagerTransactor: VoterManagerTransactor{contract: contract}, VoterManagerFilterer: VoterManagerFilterer{contract: contract}}, nil +} + +// NewVoterManagerCaller creates a new read-only instance of VoterManager, bound to a specific deployed contract. +func NewVoterManagerCaller(address common.Address, caller bind.ContractCaller) (*VoterManagerCaller, error) { + contract, err := bindVoterManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VoterManagerCaller{contract: contract}, nil +} + +// NewVoterManagerTransactor creates a new write-only instance of VoterManager, bound to a specific deployed contract. +func NewVoterManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*VoterManagerTransactor, error) { + contract, err := bindVoterManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VoterManagerTransactor{contract: contract}, nil +} + +// NewVoterManagerFilterer creates a new log filterer instance of VoterManager, bound to a specific deployed contract. +func NewVoterManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*VoterManagerFilterer, error) { + contract, err := bindVoterManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VoterManagerFilterer{contract: contract}, nil +} + +// bindVoterManager binds a generic wrapper to an already deployed contract. +func bindVoterManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(VoterManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_VoterManager *VoterManagerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _VoterManager.Contract.VoterManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_VoterManager *VoterManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VoterManager.Contract.VoterManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_VoterManager *VoterManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VoterManager.Contract.VoterManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_VoterManager *VoterManagerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _VoterManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_VoterManager *VoterManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VoterManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_VoterManager *VoterManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VoterManager.Contract.contract.Transact(opts, method, params...) +} + +// GetPendingOpDetails is a free data retrieval call binding the contract method 0x014e6acc. +// +// Solidity: function getPendingOpDetails(_orgId string) constant returns(string, string, address, uint256) +func (_VoterManager *VoterManagerCaller) GetPendingOpDetails(opts *bind.CallOpts, _orgId string) (string, string, common.Address, *big.Int, error) { + var ( + ret0 = new(string) + ret1 = new(string) + ret2 = new(common.Address) + ret3 = new(*big.Int) + ) + out := &[]interface{}{ + ret0, + ret1, + ret2, + ret3, + } + err := _VoterManager.contract.Call(opts, out, "getPendingOpDetails", _orgId) + return *ret0, *ret1, *ret2, *ret3, err +} + +// GetPendingOpDetails is a free data retrieval call binding the contract method 0x014e6acc. +// +// Solidity: function getPendingOpDetails(_orgId string) constant returns(string, string, address, uint256) +func (_VoterManager *VoterManagerSession) GetPendingOpDetails(_orgId string) (string, string, common.Address, *big.Int, error) { + return _VoterManager.Contract.GetPendingOpDetails(&_VoterManager.CallOpts, _orgId) +} + +// GetPendingOpDetails is a free data retrieval call binding the contract method 0x014e6acc. +// +// Solidity: function getPendingOpDetails(_orgId string) constant returns(string, string, address, uint256) +func (_VoterManager *VoterManagerCallerSession) GetPendingOpDetails(_orgId string) (string, string, common.Address, *big.Int, error) { + return _VoterManager.Contract.GetPendingOpDetails(&_VoterManager.CallOpts, _orgId) +} + +// AddVoter is a paid mutator transaction binding the contract method 0x5607395b. +// +// Solidity: function addVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerTransactor) AddVoter(opts *bind.TransactOpts, _orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.contract.Transact(opts, "addVoter", _orgId, _vAccount) +} + +// AddVoter is a paid mutator transaction binding the contract method 0x5607395b. +// +// Solidity: function addVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerSession) AddVoter(_orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.Contract.AddVoter(&_VoterManager.TransactOpts, _orgId, _vAccount) +} + +// AddVoter is a paid mutator transaction binding the contract method 0x5607395b. +// +// Solidity: function addVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerTransactorSession) AddVoter(_orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.Contract.AddVoter(&_VoterManager.TransactOpts, _orgId, _vAccount) +} + +// AddVotingItem is a paid mutator transaction binding the contract method 0xe98ac22d. +// +// Solidity: function addVotingItem(_authOrg string, _orgId string, _enodeId string, _account address, _pendingOp uint256) returns() +func (_VoterManager *VoterManagerTransactor) AddVotingItem(opts *bind.TransactOpts, _authOrg string, _orgId string, _enodeId string, _account common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.contract.Transact(opts, "addVotingItem", _authOrg, _orgId, _enodeId, _account, _pendingOp) +} + +// AddVotingItem is a paid mutator transaction binding the contract method 0xe98ac22d. +// +// Solidity: function addVotingItem(_authOrg string, _orgId string, _enodeId string, _account address, _pendingOp uint256) returns() +func (_VoterManager *VoterManagerSession) AddVotingItem(_authOrg string, _orgId string, _enodeId string, _account common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.Contract.AddVotingItem(&_VoterManager.TransactOpts, _authOrg, _orgId, _enodeId, _account, _pendingOp) +} + +// AddVotingItem is a paid mutator transaction binding the contract method 0xe98ac22d. +// +// Solidity: function addVotingItem(_authOrg string, _orgId string, _enodeId string, _account address, _pendingOp uint256) returns() +func (_VoterManager *VoterManagerTransactorSession) AddVotingItem(_authOrg string, _orgId string, _enodeId string, _account common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.Contract.AddVotingItem(&_VoterManager.TransactOpts, _authOrg, _orgId, _enodeId, _account, _pendingOp) +} + +// DeleteVoter is a paid mutator transaction binding the contract method 0x59cbd6fe. +// +// Solidity: function deleteVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerTransactor) DeleteVoter(opts *bind.TransactOpts, _orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.contract.Transact(opts, "deleteVoter", _orgId, _vAccount) +} + +// DeleteVoter is a paid mutator transaction binding the contract method 0x59cbd6fe. +// +// Solidity: function deleteVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerSession) DeleteVoter(_orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.Contract.DeleteVoter(&_VoterManager.TransactOpts, _orgId, _vAccount) +} + +// DeleteVoter is a paid mutator transaction binding the contract method 0x59cbd6fe. +// +// Solidity: function deleteVoter(_orgId string, _vAccount address) returns() +func (_VoterManager *VoterManagerTransactorSession) DeleteVoter(_orgId string, _vAccount common.Address) (*types.Transaction, error) { + return _VoterManager.Contract.DeleteVoter(&_VoterManager.TransactOpts, _orgId, _vAccount) +} + +// ProcessVote is a paid mutator transaction binding the contract method 0xb0213864. +// +// Solidity: function processVote(_authOrg string, _vAccount address, _pendingOp uint256) returns(bool) +func (_VoterManager *VoterManagerTransactor) ProcessVote(opts *bind.TransactOpts, _authOrg string, _vAccount common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.contract.Transact(opts, "processVote", _authOrg, _vAccount, _pendingOp) +} + +// ProcessVote is a paid mutator transaction binding the contract method 0xb0213864. +// +// Solidity: function processVote(_authOrg string, _vAccount address, _pendingOp uint256) returns(bool) +func (_VoterManager *VoterManagerSession) ProcessVote(_authOrg string, _vAccount common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.Contract.ProcessVote(&_VoterManager.TransactOpts, _authOrg, _vAccount, _pendingOp) +} + +// ProcessVote is a paid mutator transaction binding the contract method 0xb0213864. +// +// Solidity: function processVote(_authOrg string, _vAccount address, _pendingOp uint256) returns(bool) +func (_VoterManager *VoterManagerTransactorSession) ProcessVote(_authOrg string, _vAccount common.Address, _pendingOp *big.Int) (*types.Transaction, error) { + return _VoterManager.Contract.ProcessVote(&_VoterManager.TransactOpts, _authOrg, _vAccount, _pendingOp) +} + +// VoterManagerVoteProcessedIterator is returned from FilterVoteProcessed and is used to iterate over the raw logs and unpacked data for VoteProcessed events raised by the VoterManager contract. +type VoterManagerVoteProcessedIterator struct { + Event *VoterManagerVoteProcessed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *VoterManagerVoteProcessedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoteProcessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoteProcessed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *VoterManagerVoteProcessedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *VoterManagerVoteProcessedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// VoterManagerVoteProcessed represents a VoteProcessed event raised by the VoterManager contract. +type VoterManagerVoteProcessed struct { + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterVoteProcessed is a free log retrieval operation binding the contract event 0x87999b54e45aa02834a1265e356d7bcdceb72b8cbb4396ebaeba32a103b43508. +// +// Solidity: e VoteProcessed(_orgId string) +func (_VoterManager *VoterManagerFilterer) FilterVoteProcessed(opts *bind.FilterOpts) (*VoterManagerVoteProcessedIterator, error) { + + logs, sub, err := _VoterManager.contract.FilterLogs(opts, "VoteProcessed") + if err != nil { + return nil, err + } + return &VoterManagerVoteProcessedIterator{contract: _VoterManager.contract, event: "VoteProcessed", logs: logs, sub: sub}, nil +} + +// WatchVoteProcessed is a free log subscription operation binding the contract event 0x87999b54e45aa02834a1265e356d7bcdceb72b8cbb4396ebaeba32a103b43508. +// +// Solidity: e VoteProcessed(_orgId string) +func (_VoterManager *VoterManagerFilterer) WatchVoteProcessed(opts *bind.WatchOpts, sink chan<- *VoterManagerVoteProcessed) (event.Subscription, error) { + + logs, sub, err := _VoterManager.contract.WatchLogs(opts, "VoteProcessed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(VoterManagerVoteProcessed) + if err := _VoterManager.contract.UnpackLog(event, "VoteProcessed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// VoterManagerVoterAddedIterator is returned from FilterVoterAdded and is used to iterate over the raw logs and unpacked data for VoterAdded events raised by the VoterManager contract. +type VoterManagerVoterAddedIterator struct { + Event *VoterManagerVoterAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *VoterManagerVoterAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoterAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoterAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *VoterManagerVoterAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *VoterManagerVoterAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// VoterManagerVoterAdded represents a VoterAdded event raised by the VoterManager contract. +type VoterManagerVoterAdded struct { + OrgId string + VAccount common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterVoterAdded is a free log retrieval operation binding the contract event 0x424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d34574. +// +// Solidity: e VoterAdded(_orgId string, _vAccount address) +func (_VoterManager *VoterManagerFilterer) FilterVoterAdded(opts *bind.FilterOpts) (*VoterManagerVoterAddedIterator, error) { + + logs, sub, err := _VoterManager.contract.FilterLogs(opts, "VoterAdded") + if err != nil { + return nil, err + } + return &VoterManagerVoterAddedIterator{contract: _VoterManager.contract, event: "VoterAdded", logs: logs, sub: sub}, nil +} + +// WatchVoterAdded is a free log subscription operation binding the contract event 0x424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d34574. +// +// Solidity: e VoterAdded(_orgId string, _vAccount address) +func (_VoterManager *VoterManagerFilterer) WatchVoterAdded(opts *bind.WatchOpts, sink chan<- *VoterManagerVoterAdded) (event.Subscription, error) { + + logs, sub, err := _VoterManager.contract.WatchLogs(opts, "VoterAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(VoterManagerVoterAdded) + if err := _VoterManager.contract.UnpackLog(event, "VoterAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// VoterManagerVoterDeletedIterator is returned from FilterVoterDeleted and is used to iterate over the raw logs and unpacked data for VoterDeleted events raised by the VoterManager contract. +type VoterManagerVoterDeletedIterator struct { + Event *VoterManagerVoterDeleted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *VoterManagerVoterDeletedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoterDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(VoterManagerVoterDeleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *VoterManagerVoterDeletedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *VoterManagerVoterDeletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// VoterManagerVoterDeleted represents a VoterDeleted event raised by the VoterManager contract. +type VoterManagerVoterDeleted struct { + OrgId string + VAccount common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterVoterDeleted is a free log retrieval operation binding the contract event 0x654cd85d9b2abaf3affef0a047625d088e6e4d0448935c9b5016b5f5aa0ca3b6. +// +// Solidity: e VoterDeleted(_orgId string, _vAccount address) +func (_VoterManager *VoterManagerFilterer) FilterVoterDeleted(opts *bind.FilterOpts) (*VoterManagerVoterDeletedIterator, error) { + + logs, sub, err := _VoterManager.contract.FilterLogs(opts, "VoterDeleted") + if err != nil { + return nil, err + } + return &VoterManagerVoterDeletedIterator{contract: _VoterManager.contract, event: "VoterDeleted", logs: logs, sub: sub}, nil +} + +// WatchVoterDeleted is a free log subscription operation binding the contract event 0x654cd85d9b2abaf3affef0a047625d088e6e4d0448935c9b5016b5f5aa0ca3b6. +// +// Solidity: e VoterDeleted(_orgId string, _vAccount address) +func (_VoterManager *VoterManagerFilterer) WatchVoterDeleted(opts *bind.WatchOpts, sink chan<- *VoterManagerVoterDeleted) (event.Subscription, error) { + + logs, sub, err := _VoterManager.contract.WatchLogs(opts, "VoterDeleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(VoterManagerVoterDeleted) + if err := _VoterManager.contract.UnpackLog(event, "VoterDeleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// VoterManagerVotingItemAddedIterator is returned from FilterVotingItemAdded and is used to iterate over the raw logs and unpacked data for VotingItemAdded events raised by the VoterManager contract. +type VoterManagerVotingItemAddedIterator struct { + Event *VoterManagerVotingItemAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *VoterManagerVotingItemAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(VoterManagerVotingItemAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(VoterManagerVotingItemAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *VoterManagerVotingItemAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *VoterManagerVotingItemAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// VoterManagerVotingItemAdded represents a VotingItemAdded event raised by the VoterManager contract. +type VoterManagerVotingItemAdded struct { + OrgId string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterVotingItemAdded is a free log retrieval operation binding the contract event 0x5bfaebb5931145594f63236d2a59314c4dc6035b65d0ca4cee9c7298e2f06ca3. +// +// Solidity: e VotingItemAdded(_orgId string) +func (_VoterManager *VoterManagerFilterer) FilterVotingItemAdded(opts *bind.FilterOpts) (*VoterManagerVotingItemAddedIterator, error) { + + logs, sub, err := _VoterManager.contract.FilterLogs(opts, "VotingItemAdded") + if err != nil { + return nil, err + } + return &VoterManagerVotingItemAddedIterator{contract: _VoterManager.contract, event: "VotingItemAdded", logs: logs, sub: sub}, nil +} + +// WatchVotingItemAdded is a free log subscription operation binding the contract event 0x5bfaebb5931145594f63236d2a59314c4dc6035b65d0ca4cee9c7298e2f06ca3. +// +// Solidity: e VotingItemAdded(_orgId string) +func (_VoterManager *VoterManagerFilterer) WatchVotingItemAdded(opts *bind.WatchOpts, sink chan<- *VoterManagerVotingItemAdded) (event.Subscription, error) { + + logs, sub, err := _VoterManager.contract.WatchLogs(opts, "VotingItemAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(VoterManagerVotingItemAdded) + if err := _VoterManager.contract.UnpackLog(event, "VotingItemAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/permission/contract/AccountManager.sol b/permission/contract/AccountManager.sol new file mode 100644 index 0000000000..25bc7786ef --- /dev/null +++ b/permission/contract/AccountManager.sol @@ -0,0 +1,362 @@ +pragma solidity ^0.5.3; + +import "./PermissionsUpgradable.sol"; + +/** @title Account manager contract + * @notice This contract holds implementation logic for all account management + functionality. This can be called only by the implementation contract only. + there are few view functions exposed as public and can be called directly. + these are invoked by quorum for populating permissions data in cache + * @dev account status is denoted by a fixed integer value. The values are + as below: + 0 - Not in list + 1 - Account pending approval + 2 - Active + 3 - Inactive + 4 - Suspended + 5 - Blacklisted + 6 - Revoked + 7 - Recovery Initiated for blacklisted accounts and pending approval + from network admins + Once the account is blacklisted no further activity on the account is + possible. + When adding a new org admin account to an existing org, the existing org + admin account will be in revoked status and can be assigned a new role + later + */ +contract AccountManager { + PermissionsUpgradable private permUpgradable; + struct AccountAccessDetails { + address account; + string orgId; + string role; + uint status; + bool orgAdmin; + } + + AccountAccessDetails[] private accountAccessList; + mapping(address => uint) private accountIndex; + uint private numAccounts; + + string private adminRole; + string private orgAdminRole; + + mapping(bytes32 => address) private orgAdminIndex; + + // account permission events + event AccountAccessModified(address _account, string _orgId, string _roleId, bool _orgAdmin, uint _status); + event AccountAccessRevoked(address _account, string _orgId, string _roleId, bool _orgAdmin); + event AccountStatusChanged(address _account, string _orgId, uint _status); + + /** @notice confirms that the caller is the address of implementation + contract + */ + modifier onlyImplementation { + require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); + _; + } + + /** @notice checks if the account is exists and belongs to the org id passed + * @param _orgId - org id + * @param _account - account id + */ + modifier accountExists(string memory _orgId, address _account) { + require((accountIndex[_account]) != 0, "account does not exists"); + require(keccak256(abi.encode(accountAccessList[_getAccountIndex(_account)].orgId)) == keccak256(abi.encode(_orgId)), "account in different org"); + _; + } + + /// @notice constructor. sets the permissions upgradable address + constructor (address _permUpgradable) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + } + + + /** @notice returns the account details for a given account + * @param _account account id + * @return account id + * @return org id of the account + * @return role linked to the account + * @return status of the account + * @return bool indicating if the account is an org admin + */ + function getAccountDetails(address _account) external view returns (address, + string memory, string memory, uint, bool){ + if (accountIndex[_account] == 0) { + return (_account, "NONE", "", 0, false); + } + uint aIndex = _getAccountIndex(_account); + return (accountAccessList[aIndex].account, accountAccessList[aIndex].orgId, + accountAccessList[aIndex].role, accountAccessList[aIndex].status, + accountAccessList[aIndex].orgAdmin); + } + + /** @notice returns the account details a given account index + * @param _aIndex account index + * @return account id + * @return org id of the account + * @return role linked to the account + * @return status of the account + * @return bool indicating if the account is an org admin + */ + function getAccountDetailsFromIndex(uint _aIndex) external view returns + (address, string memory, string memory, uint, bool) { + return (accountAccessList[_aIndex].account, + accountAccessList[_aIndex].orgId, accountAccessList[_aIndex].role, + accountAccessList[_aIndex].status, accountAccessList[_aIndex].orgAdmin); + } + + /** @notice returns the total number of accounts + * @return total number accounts + */ + function getNumberOfAccounts() external view returns (uint) { + return accountAccessList.length; + } + + /** @notice this is called at the time of network initialization to set + the default values of network admin and org admin roles + */ + function setDefaults(string calldata _nwAdminRole, string calldata _oAdminRole) + external onlyImplementation { + adminRole = _nwAdminRole; + orgAdminRole = _oAdminRole; + } + + /** @notice this function is called to assign the org admin or network + admin roles only to the passed account + * @param _account - account id + * @param _orgId - org to which it belongs + * @param _roleId - role id to be assigned + * @param _status - account status to be assigned + */ + function assignAdminRole(address _account, string calldata _orgId, + string calldata _roleId, uint _status) external onlyImplementation { + require(((keccak256(abi.encode(_roleId)) == keccak256(abi.encode(orgAdminRole))) || + (keccak256(abi.encode(_roleId)) == keccak256(abi.encode(adminRole)))), + "can be called to assign admin roles only"); + + _setAccountRole(_account, _orgId, _roleId, _status, true); + + } + + /** @notice this function is called to assign the any role to the passed + account. + * @param _account - account id + * @param _orgId - org to which it belongs + * @param _roleId - role id to be assigned + * @param _adminRole - indicates of the role is an admin role + */ + function assignAccountRole(address _account, string calldata _orgId, + string calldata _roleId, bool _adminRole) external onlyImplementation { + require(((keccak256(abi.encode(_roleId)) != keccak256(abi.encode(adminRole))) + && (keccak256(abi.encode(abi.encode(_roleId))) != keccak256(abi.encode(orgAdminRole)))), + "cannot be called fro assigning org admin and network admin roles"); + _setAccountRole(_account, _orgId, _roleId, 2, _adminRole); + } + + /** @notice this function removes existing admin account. will be called at + the time of adding a new account as org admin account. at org + level there can be one org admin account only + * @param _orgId - org id + * @return bool to indicate if voter update is required or not + * @return _adminRole - indicates of the role is an admin role + */ + function removeExistingAdmin(string calldata _orgId) external + onlyImplementation + returns (bool voterUpdate, address account) { + // change the status of existing org admin to revoked + if (orgAdminExists(_orgId)) { + uint id = _getAccountIndex(orgAdminIndex[keccak256(abi.encode(_orgId))]); + accountAccessList[id].status = 6; + accountAccessList[id].orgAdmin = false; + emit AccountAccessModified(accountAccessList[id].account, + accountAccessList[id].orgId, accountAccessList[id].role, + accountAccessList[id].orgAdmin, accountAccessList[id].status); + return ((keccak256(abi.encode(accountAccessList[id].role)) == keccak256(abi.encode(adminRole))), + accountAccessList[id].account); + } + return (false, address(0)); + } + + /** @notice function to add an account as network admin or org admin. + * @param _orgId - org id + * @param _account - account id + * @return bool to indicate if voter update is required or not + */ + function addNewAdmin(string calldata _orgId, address _account) external + onlyImplementation + returns (bool voterUpdate) { + // check of the account role is org admin role and status is pending + // approval. if yes update the status to approved + string memory role = getAccountRole(_account); + uint status = _getAccountStatus(_account); + uint id = _getAccountIndex(_account); + if ((keccak256(abi.encode(role)) == keccak256(abi.encode(orgAdminRole))) && + (status == 1)) { + orgAdminIndex[keccak256(abi.encode(_orgId))] = _account; + } + accountAccessList[id].status = 2; + accountAccessList[id].orgAdmin = true; + emit AccountAccessModified(_account, accountAccessList[id].orgId, accountAccessList[id].role, + accountAccessList[id].orgAdmin, accountAccessList[id].status); + return (keccak256(abi.encode(accountAccessList[id].role)) == keccak256(abi.encode(adminRole))); + } + + /** @notice updates the account status to the passed status value + * @param _orgId - org id + * @param _account - account id + * @param _action - new status of the account + * @dev the following actions are allowed + 1 - Suspend the account + 2 - Reactivate a suspended account + 3 - Blacklist an account + 4 - Initiate recovery for black listed account + 5 - Complete recovery of black listed account and update status to active + */ + function updateAccountStatus(string calldata _orgId, address _account, uint _action) external + onlyImplementation + accountExists(_orgId, _account) { + require((_action > 0 && _action < 6), "invalid status change request"); + + // check if the account is org admin. if yes then do not allow any status change + require(checkOrgAdmin(_account, _orgId, "") != true, "status change not possible for org admin accounts"); + uint newStatus; + if (_action == 1) { + // for suspending an account current status should be active + require(accountAccessList[_getAccountIndex(_account)].status == 2, + "account is not in active status. operation cannot be done"); + newStatus = 4; + } + else if (_action == 2) { + // for reactivating a suspended account, current status should be suspended + require(accountAccessList[_getAccountIndex(_account)].status == 4, + "account is not in suspended status. operation cannot be done"); + newStatus = 2; + } + else if (_action == 3) { + require(accountAccessList[_getAccountIndex(_account)].status != 5, + "account is already blacklisted. operation cannot be done"); + newStatus = 5; + } + else if (_action == 4) { + require(accountAccessList[_getAccountIndex(_account)].status == 5, + "account is not blacklisted. operation cannot be done"); + newStatus = 7; + } + else if (_action == 5) { + require(accountAccessList[_getAccountIndex(_account)].status == 7, "account recovery not initiated. operation cannot be done"); + newStatus = 2; + } + + accountAccessList[_getAccountIndex(_account)].status = newStatus; + emit AccountStatusChanged(_account, _orgId, newStatus); + } + + /** @notice checks if the passed account exists and if exists does it + belong to the passed organization. + * @param _account - account id + * @param _orgId - org id + * @return bool true if the account does not exists or exists and belongs + * @return passed org + */ + function validateAccount(address _account, string calldata _orgId) external + view returns (bool){ + if (accountIndex[_account] == 0) { + return true; + } + uint256 id = _getAccountIndex(_account); + return (keccak256(abi.encode(accountAccessList[id].orgId)) == keccak256(abi.encode(_orgId))); + } + + /** @notice checks if org admin account exists for the passed org id + * @param _orgId - org id + * @return true if the org admin account exists and is approved + */ + function orgAdminExists(string memory _orgId) public view returns (bool) { + if (orgAdminIndex[keccak256(abi.encode(_orgId))] != address(0)) { + address adminAcct = orgAdminIndex[keccak256(abi.encode(_orgId))]; + return _getAccountStatus(adminAcct) == 2; + } + return false; + + } + + /** @notice returns the role id linked to the passed account + * @param _account account id + * @return role id + */ + function getAccountRole(address _account) public view returns (string memory) { + if (accountIndex[_account] == 0) { + return "NONE"; + } + uint256 acctIndex = _getAccountIndex(_account); + if (accountAccessList[acctIndex].status != 0) { + return accountAccessList[acctIndex].role; + } + else { + return "NONE"; + } + } + + /** @notice checks if the account is a org admin for the passed org or + for the ultimate parent organization + * @param _account account id + * @param _orgId org id + * @param _ultParent master org id or + */ + function checkOrgAdmin(address _account, string memory _orgId, + string memory _ultParent) public view returns (bool) { + // check if the account role is network admin. If yes return success + if (keccak256(abi.encode(getAccountRole(_account))) == keccak256(abi.encode(adminRole))) { + // check of the orgid is network admin org. then return true + uint256 id = _getAccountIndex(_account); + return ((keccak256(abi.encode(accountAccessList[id].orgId)) == keccak256(abi.encode(_orgId))) + || (keccak256(abi.encode(accountAccessList[id].orgId)) == keccak256(abi.encode(_ultParent)))); + } + return ((orgAdminIndex[keccak256(abi.encode(_orgId))] == _account) || (orgAdminIndex[keccak256(abi.encode(_ultParent))] == _account)); + } + + /** @notice returns the index for a given account id + * @param _account account id + * @return account index + */ + function _getAccountIndex(address _account) internal view returns (uint256) { + return accountIndex[_account] - 1; + } + + /** @notice returns the account status for a given account + * @param _account account id + * @return account status + */ + function _getAccountStatus(address _account) internal view returns (uint256) { + if (accountIndex[_account] == 0) { + return 0; + } + uint256 aIndex = _getAccountIndex(_account); + return (accountAccessList[aIndex].status); + } + + /** @notice sets the account role to the passed role id and sets the status + * @param _account account id + * @param _orgId org id + * @param _status status to be set + * @param _oAdmin bool to indicate if account is org admin + */ + function _setAccountRole(address _account, string memory _orgId, + string memory _roleId, uint256 _status, bool _oAdmin) internal onlyImplementation { + // Check if account already exists + uint256 aIndex = _getAccountIndex(_account); + if (accountIndex[_account] != 0) { + accountAccessList[aIndex].role = _roleId; + accountAccessList[aIndex].status = _status; + accountAccessList[aIndex].orgAdmin = _oAdmin; + } + else { + numAccounts ++; + accountIndex[_account] = numAccounts; + accountAccessList.push(AccountAccessDetails(_account, _orgId, + _roleId, _status, _oAdmin)); + } + emit AccountAccessModified(_account, _orgId, _roleId, _oAdmin, _status); + } +} diff --git a/permission/contract/NodeManager.sol b/permission/contract/NodeManager.sol new file mode 100644 index 0000000000..4bfb71bde3 --- /dev/null +++ b/permission/contract/NodeManager.sol @@ -0,0 +1,254 @@ +pragma solidity ^0.5.3; + +import "./PermissionsUpgradable.sol"; +/** @title Node manager contract + * @notice This contract holds implementation logic for all node management + functionality. This can be called only by the implementation contract. + There are few view functions exposed as public and can be called directly. + These are invoked by quorum for populating permissions data in cache + * @dev node status is denoted by a fixed integer value. The values are + as below: + 0 - Not in list + 1 - Node pending approval + 2 - Active + 3 - Deactivated + 4 - Blacklisted + 5 - Blacklisted node recovery initiated. Once approved the node + status will be updated to Active (2) + Once the node is blacklisted no further activity on the node is + possible. + */ +contract NodeManager { + PermissionsUpgradable private permUpgradable; + struct NodeDetails { + string enodeId; //e.g. 127.0.0.1:20005 + string orgId; + uint256 status; + } + // use an array to store node details + // if we want to list all node one day, mapping is not capable + NodeDetails[] private nodeList; + // mapping of enodeid to array index to track node + mapping(bytes32 => uint256) private nodeIdToIndex; + // tracking total number of nodes in network + uint256 private numberOfNodes; + + + // node permission events for new node propose + event NodeProposed(string _enodeId, string _orgId); + event NodeApproved(string _enodeId, string _orgId); + + // node permission events for node deactivation + event NodeDeactivated(string _enodeId, string _orgId); + + // node permission events for node activation + event NodeActivated(string _enodeId, string _orgId); + + // node permission events for node blacklist + event NodeBlacklisted(string _enodeId, string _orgId); + + // node permission events for initiating the recovery of blacklisted + // node + event NodeRecoveryInitiated(string _enodeId, string _orgId); + + // node permission events for completing the recovery of blacklisted + // node + event NodeRecoveryCompleted(string _enodeId, string _orgId); + + /** @notice confirms that the caller is the address of implementation + contract + */ + modifier onlyImplementation { + require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); + _; + } + + /** @notice checks if the node exists in the network + * @param _enodeId full enode id + */ + modifier enodeExists(string memory _enodeId) { + require(nodeIdToIndex[keccak256(abi.encode(_enodeId))] != 0, + "passed enode id does not exist"); + _; + } + + /** @notice checks if the node does not exist in the network + * @param _enodeId full enode id + */ + modifier enodeDoesNotExists(string memory _enodeId) { + require(nodeIdToIndex[keccak256(abi.encode(_enodeId))] == 0, + "passed enode id exists"); + _; + } + + /** @notice constructor. sets the permissions upgradable address + */ + constructor (address _permUpgradable) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + } + + /** @notice fetches the node details given an enode id + * @param _enodeId full enode id + * @return org id + * @return enode id + * @return status of the node + */ + function getNodeDetails(string calldata enodeId) external view + returns (string memory _orgId, string memory _enodeId, uint256 _nodeStatus) { + uint256 nodeIndex = _getNodeIndex(enodeId); + return (nodeList[nodeIndex].orgId, nodeList[nodeIndex].enodeId, + nodeList[nodeIndex].status); + } + + /** @notice fetches the node details given the index of the enode + * @param _nodeIndex node index + * @return org id + * @return enode id + * @return status of the node + */ + function getNodeDetailsFromIndex(uint256 _nodeIndex) external view + returns (string memory _orgId, string memory _enodeId, uint256 _nodeStatus) { + return (nodeList[_nodeIndex].orgId, nodeList[_nodeIndex].enodeId, + nodeList[_nodeIndex].status); + } + + /** @notice returns the total number of enodes in the network + * @return number of nodes + */ + function getNumberOfNodes() external view returns (uint256) { + return numberOfNodes; + } + + /** @notice called at the time of network initialization for adding + admin nodes + * @param _enodeId enode id + * @param _orgId org id to which the enode belongs + */ + function addAdminNode(string calldata _enodeId, string calldata _orgId) external + onlyImplementation + enodeDoesNotExists(_enodeId) { + numberOfNodes++; + nodeIdToIndex[keccak256(abi.encode(_enodeId))] = numberOfNodes; + nodeList.push(NodeDetails(_enodeId, _orgId, 2)); + emit NodeApproved(_enodeId, _orgId); + } + + /** @notice called at the time of new org creation to add node to org + * @param _enodeId enode id + * @param _orgId org id to which the enode belongs + */ + function addNode(string calldata _enodeId, string calldata _orgId) external + onlyImplementation + enodeDoesNotExists(_enodeId) { + numberOfNodes++; + nodeIdToIndex[keccak256(abi.encode(_enodeId))] = numberOfNodes; + nodeList.push(NodeDetails(_enodeId, _orgId, 1)); + emit NodeProposed(_enodeId, _orgId); + } + + /** @notice called org admins to add new enodes to the org or sub orgs + * @param _enodeId enode id + * @param _orgId org or sub org id to which the enode belongs + */ + function addOrgNode(string calldata _enodeId, string calldata _orgId) external + onlyImplementation + enodeDoesNotExists(_enodeId) { + numberOfNodes++; + nodeIdToIndex[keccak256(abi.encode(_enodeId))] = numberOfNodes; + nodeList.push(NodeDetails(_enodeId, _orgId, 2)); + emit NodeApproved(_enodeId, _orgId); + } + + /** @notice function to approve the node addition. only called at the time + master org creation by network admin + * @param _enodeId enode id + * @param _orgId org or sub org id to which the enode belongs + */ + function approveNode(string calldata _enodeId, string calldata _orgId) external + onlyImplementation + enodeExists(_enodeId) { + // node should belong to the passed org + require(_checkOrg(_enodeId, _orgId), "enode id does not belong to the passed org id"); + require(_getNodeStatus(_enodeId) == 1, "nothing pending for approval"); + uint256 nodeIndex = _getNodeIndex(_enodeId); + nodeList[nodeIndex].status = 2; + emit NodeApproved(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].orgId); + } + + /** @notice updates the node status. can be called for deactivating/ + blacklisting and reactivating a deactivated node + * @param _enodeId enode id + * @param _orgId org or sub org id to which the enode belong + * @param _action action being performed + * @dev action can have any of the following values + 1 - Suspend the node + 2 - Revoke suspension of a suspended node + 3 - blacklist a node + 4 - initiate the recovery of a blacklisted node + 5 - blacklisted node recovery fully approved. mark to active + */ + function updateNodeStatus(string calldata _enodeId, string calldata _orgId, uint256 _action) external + onlyImplementation + enodeExists(_enodeId) { + // node should belong to the org + require(_checkOrg(_enodeId, _orgId), "enode id does not belong to the passed org"); + require((_action == 1 || _action == 2 || _action == 3 || _action == 4 || _action == 5), + "invalid operation. wrong action passed"); + + if (_action == 1) { + require(_getNodeStatus(_enodeId) == 2, "operation cannot be performed"); + nodeList[_getNodeIndex(_enodeId)].status = 3; + emit NodeDeactivated(_enodeId, _orgId); + } + else if (_action == 2) { + require(_getNodeStatus(_enodeId) == 3, "operation cannot be performed"); + nodeList[_getNodeIndex(_enodeId)].status = 2; + emit NodeActivated(_enodeId, _orgId); + } + else if (_action == 3) { + nodeList[_getNodeIndex(_enodeId)].status = 4; + emit NodeBlacklisted(_enodeId, _orgId); + } else if (_action == 4) { + // node should be in blacklisted state + require(_getNodeStatus(_enodeId) == 4, "operation cannot be performed"); + nodeList[_getNodeIndex(_enodeId)].status = 5; + emit NodeRecoveryInitiated(_enodeId, _orgId); + } else { + // node should be in initiated recovery state + require(_getNodeStatus(_enodeId) == 5, "operation cannot be performed"); + nodeList[_getNodeIndex(_enodeId)].status = 2; + emit NodeRecoveryCompleted(_enodeId, _orgId); + } + } + + // private functions + /** @notice returns the node index for given enode id + * @param _enodeId enode id + * @return trur or false + */ + function _getNodeIndex(string memory _enodeId) internal view + returns (uint256) { + return nodeIdToIndex[keccak256(abi.encode(_enodeId))] - 1; + } + + /** @notice checks if enode id is linked to the org id passed + * @param _enodeId enode id + * @param _orgId org or sub org id to which the enode belongs + * @return true or false + */ + function _checkOrg(string memory _enodeId, string memory _orgId) internal view + returns (bool) { + return (keccak256(abi.encode(nodeList[_getNodeIndex(_enodeId)].orgId)) == keccak256(abi.encode(_orgId))); + } + + /** @notice returns the node status for a given enode id + * @param _enodeId enode id + * @return node status + */ + function _getNodeStatus(string memory _enodeId) internal view returns (uint256) { + if (nodeIdToIndex[keccak256(abi.encode(_enodeId))] == 0) { + return 0; + } + return nodeList[_getNodeIndex(_enodeId)].status; + } +} diff --git a/permission/contract/OrgManager.sol b/permission/contract/OrgManager.sol new file mode 100644 index 0000000000..ca1826f184 --- /dev/null +++ b/permission/contract/OrgManager.sol @@ -0,0 +1,341 @@ +pragma solidity ^0.5.3; + +import "./PermissionsUpgradable.sol"; +/** @title Organization manager contract + * @notice This contract holds implementation logic for all org management + functionality. This can be called only by the implementation + contract only. there are few view functions exposed as public and + can be called directly. these are invoked by quorum for populating + permissions data in cache + * @dev the status of the organization is denoted by a set of integer + values. These are as below: + 0 - Not in list, + 1 - Org proposed for approval by network admins + 2 - Org in Approved status + 3 - Org proposed for suspension and pending approval by network admins + 4 - Org in Suspended, + Once the node is blacklisted no further activity on the node is + possible. + */ +contract OrgManager { + string private adminOrgId; + PermissionsUpgradable private permUpgradable; + // checks if first time network boot up has happened or not + bool private networkBoot = false; + + // variables which control the breadth and depth of the sub org tree + uint private DEPTH_LIMIT = 4; + uint private BREADTH_LIMIT = 4; + struct OrgDetails { + string orgId; + uint status; + string parentId; + string fullOrgId; + string ultParent; + uint pindex; + uint level; + uint [] subOrgIndexList; + } + + OrgDetails [] private orgList; + mapping(bytes32 => uint) private OrgIndex; + uint private orgNum = 0; + + // events related to Master Org add + event OrgApproved(string _orgId, string _porgId, string _ultParent, + uint _level, uint _status); + event OrgPendingApproval(string _orgId, string _porgId, string _ultParent, + uint _level, uint _status); + event OrgSuspended(string _orgId, string _porgId, string _ultParent, + uint _level); + event OrgSuspensionRevoked(string _orgId, string _porgId, string _ultParent, + uint _level); + + /** @notice confirms that the caller is the address of implementation + contract + */ + modifier onlyImplementation{ + require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); + _; + } + + /** @notice checks if the org id does not exists + * @param _orgId - org id + * @return true if org does not exist + */ + modifier orgDoesNotExist(string memory _orgId) { + require(checkOrgExists(_orgId) == false, "org exists"); + _; + } + + /** @notice checks if the org id does exists + * @param _orgId - org id + * @return true if org exists + */ + modifier orgExists(string memory _orgId) { + require(checkOrgExists(_orgId) == true, "org does not exist"); + _; + } + + /** @notice constructor. sets the permissions upgradable address + */ + constructor (address _permUpgradable) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + } + + /** @notice called at the time of network initialization. sets the depth + breadth for sub orgs creation. and creates the default network + admin org as per config file + */ + function setUpOrg(string calldata _orgId, uint256 _breadth, uint256 _depth) external + onlyImplementation { + _addNewOrg("", _orgId, 1, 2); + DEPTH_LIMIT = _depth; + BREADTH_LIMIT = _breadth; + } + /** @notice function for adding a new master org to the network + * @param _orgId unique org id to be added + * @dev org will be added if it does exist + */ + function addOrg(string calldata _orgId) external + onlyImplementation + orgDoesNotExist(_orgId) { + _addNewOrg("", _orgId, 1, 1); + } + + /** @notice function for adding a new sub org under a parent org + * @param _pOrgId unique org id to be added + * @dev org will be added if it does exist + */ + function addSubOrg(string calldata _pOrgId, string calldata _orgId) external + onlyImplementation + orgDoesNotExist(string(abi.encodePacked(_pOrgId, ".", _orgId))) { + _addNewOrg(_pOrgId, _orgId, 2, 2); + } + + /** @notice updates the status of a master org. + * @param _orgId unique org id to be added + * @param _action action being performed + * @dev status cannot be updated for sub orgs. + This function can be called for the following actions: + 1 - to suspend an org + 2 - to activate the org back + */ + function updateOrg(string calldata _orgId, uint256 _action) external + onlyImplementation + orgExists(_orgId) + returns (uint256){ + require((_action == 1 || _action == 2), "invalid action. operation not allowed"); + uint256 id = _getOrgIndex(_orgId); + require(orgList[id].level == 1, "not a master org. operation not allowed"); + + uint256 reqStatus; + uint256 pendingOp; + if (_action == 1) { + reqStatus = 2; + pendingOp = 2; + } + else if (_action == 2) { + reqStatus = 4; + pendingOp = 3; + } + require(checkOrgStatus(_orgId, reqStatus) == true, + "org status does not allow the operation"); + if (_action == 1) { + _suspendOrg(_orgId); + } + else { + _revokeOrgSuspension(_orgId); + } + return pendingOp; + } + + /** @notice function to approve org status change for master orgs + * @param _orgId unique org id to be added + * @param _action approval for action + * @dev status cannot be updated for sub orgs. + This function can be called for the following actions: + 1 - to suspend an org + 2 - to activate the org back + */ + function approveOrgStatusUpdate(string calldata _orgId, uint256 _action) external + onlyImplementation + orgExists(_orgId) { + if (_action == 1) { + _approveOrgSuspension(_orgId); + } + else { + _approveOrgRevokeSuspension(_orgId); + } + } + + /** @notice function to approve org status change for master orgs + * @param _orgId unique org id to be added + */ + function approveOrg(string calldata _orgId) external + onlyImplementation { + require(checkOrgStatus(_orgId, 1) == true, "nothing to approve"); + uint256 id = _getOrgIndex(_orgId); + orgList[id].status = 2; + emit OrgApproved(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level, 2); + } + + /** @notice returns org info for a given org index + * @param _orgIndex org index + * @return org id + * @return parent org id + * @return ultimate parent id + * @return level in the org tree + * @return status + */ + function getOrgInfo(uint256 _orgIndex) external view returns (string memory, + string memory, string memory, uint256, uint256) { + return (orgList[_orgIndex].orgId, orgList[_orgIndex].parentId, + orgList[_orgIndex].ultParent, orgList[_orgIndex].level, orgList[_orgIndex].status); + } + + /** @notice returns the master org id for the given org or sub org + * @param _orgId org id + * @return master org id + */ + function getUltimateParent(string calldata _orgId) external view + onlyImplementation + returns (string memory) { + return orgList[_getOrgIndex(_orgId)].ultParent; + } + + /** @notice returns the total number of orgs in the network + * @return master org id + */ + function getNumberOfOrgs() public view returns (uint256) { + return orgList.length; + } + + /** @notice confirms that org status is same as passed status + * @param _orgId org id + * @param _orgStatus org status + * @return true or false + */ + function checkOrgStatus(string memory _orgId, uint256 _orgStatus) + public view returns (bool){ + uint256 id = _getOrgIndex(_orgId); + return ((OrgIndex[keccak256(abi.encodePacked(_orgId))] != 0) + && orgList[id].status == _orgStatus); + } + + /** @notice confirms if the org exists in the network + * @param _orgId org id + * @return true or false + */ + function checkOrgExists(string memory _orgId) public view returns (bool) { + return (!(OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0)); + } + + /** @notice updates the org status to suspended + * @param _orgId org id + */ + function _suspendOrg(string memory _orgId) internal { + require(checkOrgStatus(_orgId, 2) == true, + "org not in approved status. operation cannot be done"); + uint256 id = _getOrgIndex(_orgId); + orgList[id].status = 3; + emit OrgPendingApproval(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level, 3); + } + + /** @notice revokes the suspension of an org + * @param _orgId org id + */ + function _revokeOrgSuspension(string memory _orgId) internal { + require(checkOrgStatus(_orgId, 4) == true, "org not in suspended state"); + uint256 id = _getOrgIndex(_orgId); + orgList[id].status = 5; + emit OrgPendingApproval(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level, 5); + } + + /** @notice approval function for org suspension activity + * @param _orgId org id + */ + function _approveOrgSuspension(string memory _orgId) internal { + require(checkOrgStatus(_orgId, 3) == true, "nothing to approve"); + uint256 id = _getOrgIndex(_orgId); + orgList[id].status = 4; + emit OrgSuspended(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level); + } + + /** @notice approval function for revoking org suspension + * @param _orgId org id + */ + function _approveOrgRevokeSuspension(string memory _orgId) internal { + require(checkOrgStatus(_orgId, 5) == true, "nothing to approve"); + uint256 id = _getOrgIndex(_orgId); + orgList[id].status = 2; + emit OrgSuspensionRevoked(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level); + } + + /** @notice function to add a new organization + * @param _pOrgId parent org id + * @param _orgId org id + * @param _level level in org hierarchy + * @param _status status of the org + */ + function _addNewOrg(string memory _pOrgId, string memory _orgId, + uint256 _level, uint _status) internal { + bytes32 pid = ""; + bytes32 oid = ""; + uint256 parentIndex = 0; + + if (_level == 1) {//root + oid = keccak256(abi.encodePacked(_orgId)); + } else { + pid = keccak256(abi.encodePacked(_pOrgId)); + oid = keccak256(abi.encodePacked(_pOrgId, ".", _orgId)); + } + orgNum++; + OrgIndex[oid] = orgNum; + uint256 id = orgList.length++; + if (_level == 1) { + orgList[id].level = _level; + orgList[id].pindex = 0; + orgList[id].fullOrgId = _orgId; + orgList[id].ultParent = _orgId; + } else { + parentIndex = OrgIndex[pid] - 1; + + require(orgList[parentIndex].subOrgIndexList.length < BREADTH_LIMIT, + "breadth level exceeded"); + require(orgList[parentIndex].level < DEPTH_LIMIT, + "depth level exceeded"); + + orgList[id].level = orgList[parentIndex].level + 1; + orgList[id].pindex = parentIndex; + orgList[id].ultParent = orgList[parentIndex].ultParent; + uint256 subOrgId = orgList[parentIndex].subOrgIndexList.length++; + orgList[parentIndex].subOrgIndexList[subOrgId] = id; + orgList[id].fullOrgId = string(abi.encodePacked(_pOrgId, ".", _orgId)); + } + orgList[id].orgId = _orgId; + orgList[id].parentId = _pOrgId; + orgList[id].status = _status; + if (_status == 1) { + emit OrgPendingApproval(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level, 1); + } + else { + emit OrgApproved(orgList[id].orgId, orgList[id].parentId, + orgList[id].ultParent, orgList[id].level, 2); + } + } + + /** @notice returns the org index from the org list for the given org + * @return org index + */ + function _getOrgIndex(string memory _orgId) public view returns (uint){ + return OrgIndex[keccak256(abi.encodePacked(_orgId))] - 1; + } + +} diff --git a/permission/contract/PermissionsImplementation.sol b/permission/contract/PermissionsImplementation.sol new file mode 100644 index 0000000000..9ddc68acaa --- /dev/null +++ b/permission/contract/PermissionsImplementation.sol @@ -0,0 +1,662 @@ +pragma solidity ^0.5.3; + +import "./RoleManager.sol"; +import "./AccountManager.sol"; +import "./VoterManager.sol"; +import "./NodeManager.sol"; +import "./OrgManager.sol"; +import "./PermissionsUpgradable.sol"; + +/** @title Permissions Implementation Contract + * @notice This contract holds implementation logic for all permissions + related functionality. This can be called only by the interface + contract. + */ +contract PermissionsImplementation { + AccountManager private accountManager; + RoleManager private roleManager; + VoterManager private voterManager; + NodeManager private nodeManager; + OrgManager private orgManager; + PermissionsUpgradable private permUpgradable; + + string private adminOrg; + string private adminRole; + string private orgAdminRole; + + + uint256 private fullAccess = 3; + + /** @dev this variable is meant for tracking the initial network boot up + once the network boot up is done the value is set to true + */ + bool private networkBoot = false; + + event PermissionsInitialized(bool _networkBootStatus); + + + /** @notice modifier to confirm that caller is the interface contract + */ + modifier onlyInterface{ + require(msg.sender == permUpgradable.getPermInterface(), + "can be called by interface contract only"); + _; + } + /** @notice modifier to confirm that caller is the upgradable contract + */ + modifier onlyUpgradeable { + require(msg.sender == address(permUpgradable), "invalid caller"); + _; + } + + /** @notice confirms if the network boot status is equal to passed value + * @param _status true/false + */ + modifier networkBootStatus(bool _status){ + require(networkBoot == _status, "Incorrect network boot status"); + _; + } + + /** @notice confirms that the account passed is network admin account + * @param _account account id + */ + modifier networkAdmin(address _account) { + require(isNetworkAdmin(_account) == true, "account is not a network admin account"); + _; + } + + /** @notice confirms that the account passed is org admin account + * @param _account account id + * @param _orgId org id to which the account belongs + */ + modifier orgAdmin(address _account, string memory _orgId) { + require(isOrgAdmin(_account, _orgId) == true, "account is not a org admin account"); + _; + } + + /** @notice confirms that org does not exist + * @param _orgId org id + */ + modifier orgNotExists(string memory _orgId) { + require(_checkOrgExists(_orgId) != true, "org exists"); + _; + } + + /** @notice confirms that org exists + * @param _orgId org id + */ + modifier orgExists(string memory _orgId) { + require(_checkOrgExists(_orgId) == true, "org does not exist"); + _; + } + + /** @notice checks of the passed org id is in approved status + * @param _orgId org id + */ + modifier orgApproved(string memory _orgId) { + require(checkOrgApproved(_orgId) == true, "org not in approved status"); + _; + } + + /** @notice constructor accepts the contracts addresses of other deployed + contracts of the permissions model + * @param _permUpgradable - address of permissions upgradable contract + * @param _orgManager - address of org manager contract + * @param _rolesManager - address of role manager contract + * @param _accountManager - address of account manager contract + * @param _voterManager - address of voter manager contract + * @param _nodeManager - address of node manager contract + */ + constructor (address _permUpgradable, address _orgManager, address _rolesManager, + address _accountManager, address _voterManager, address _nodeManager) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + orgManager = OrgManager(_orgManager); + roleManager = RoleManager(_rolesManager); + accountManager = AccountManager(_accountManager); + voterManager = VoterManager(_voterManager); + nodeManager = NodeManager(_nodeManager); + } + + // initial set up related functions + /** @notice for permissions its necessary to define the initial admin org + id, network admin role id and default org admin role id. this + sets these values at the time of network boot up + * @param _nwAdminOrg - address of permissions upgradable contract + * @param _nwAdminRole - address of org manager contract + * @param _oAdminRole - address of role manager contract + * @dev this function will be executed only once as part of the boot up + */ + function setPolicy(string calldata _nwAdminOrg, string calldata _nwAdminRole, + string calldata _oAdminRole) external onlyInterface + networkBootStatus(false) { + adminOrg = _nwAdminOrg; + adminRole = _nwAdminRole; + orgAdminRole = _oAdminRole; + } + + /** @notice when migrating implementation contract, the values of these + key values need to be set from the previous implementation + contract. this function allows these values to be set + * @param _nwAdminOrg - address of permissions upgradable contract + * @param _nwAdminRole - address of org manager contract + * @param _oAdminRole - address of role manager contract + * @param _networkBootStatus - network boot status true/false + */ + function setMigrationPolicy(string calldata _nwAdminOrg, string calldata _nwAdminRole, + string calldata _oAdminRole, bool _networkBootStatus) external onlyUpgradeable + networkBootStatus(false) { + adminOrg = _nwAdminOrg; + adminRole = _nwAdminRole; + orgAdminRole = _oAdminRole; + networkBoot = _networkBootStatus; + } + + /** @notice called at the time of network initialization. sets up + network admin org with allowed sub org depth and breadth + creates the network admin for the network admin org + sets the default values required by account manager contract + * @param _breadth - number of sub orgs allowed at parent level + * @param _depth - levels of sub org nesting allowed at parent level + */ + function init(uint256 _breadth, uint256 _depth) external + onlyInterface + networkBootStatus(false) { + orgManager.setUpOrg(adminOrg, _breadth, _depth); + roleManager.addRole(adminRole, adminOrg, fullAccess, true, true); + accountManager.setDefaults(adminRole, orgAdminRole); + } + /** @notice as a part of network initialization add all nodes which + are part of static-nodes.json as nodes belonging to + network admin org + * @param _enodeId - full enode id + */ + function addAdminNode(string calldata _enodeId) external + onlyInterface + networkBootStatus(false) { + nodeManager.addAdminNode(_enodeId, adminOrg); + } + + /** @notice as a part of network initialization add all accounts which are + passed via permission-config.json as network administrator + accounts + * @param _account - account id + */ + function addAdminAccount(address _account) external + onlyInterface + networkBootStatus(false) { + updateVoterList(adminOrg, _account, true); + accountManager.assignAdminRole(_account, adminOrg, adminRole, 2); + } + + /** @notice once the network initialization is complete, sets the network + boot status to true + * @return network boot status + * @dev this will be called only once from geth as a part of + * @dev network initialization + */ + function updateNetworkBootStatus() external + onlyInterface + networkBootStatus(false) + returns (bool){ + networkBoot = true; + // emit PermissionsInitialized(networkBoot); + return networkBoot; + } + + /** @notice function to add a new organization to the network. creates org + record and marks it as pending approval. adds the passed node + node manager contract. adds the account with org admin role to + account manager contracts. creates voting record for approval + by other network admin accounts + * @param _orgId unique organization id + * @param _enodeId full enode id linked to the organization + * @param _account account id. this will have the org admin privileges + */ + function addOrg(string calldata _orgId, string calldata _enodeId, + address _account, address _caller) external + onlyInterface + networkBootStatus(true) + networkAdmin(_caller) { + voterManager.addVotingItem(adminOrg, _orgId, _enodeId, _account, 1); + orgManager.addOrg(_orgId); + nodeManager.addNode(_enodeId, _orgId); + require(validateAccount(_account, _orgId) == true, + "Operation cannot be performed"); + accountManager.assignAdminRole(_account, _orgId, orgAdminRole, 1); + } + + /** @notice functions to approve a pending approval org record by networ + admin account. once majority votes are received the org is + marked as approved + * @param _orgId unique organization id + * @param _enodeId full enode id linked to the organization + * @param _account account id this will have the org admin privileges + */ + function approveOrg(string calldata _orgId, string calldata _enodeId, + address _account, address _caller) external onlyInterface networkAdmin(_caller) { + require(_checkOrgStatus(_orgId, 1) == true, "Nothing to approve"); + if ((processVote(adminOrg, _caller, 1))) { + orgManager.approveOrg(_orgId); + roleManager.addRole(orgAdminRole, _orgId, fullAccess, true, true); + nodeManager.approveNode(_enodeId, _orgId); + accountManager.addNewAdmin(_orgId, _account); + } + } + + /** @notice function to create a sub org under a given parent org. + * @param _pOrgId parent org id under which the sub org is being added + * @param _orgId unique id for the sub organization + * @param _enodeId full enode id linked to the sjb organization + * @dev _enodeId is optional. parent org id should contain the complete + org hierarchy from master org id to the immediate parent. The org + hierarchy is separated by. For example, if master org ABC has a + sub organization SUB1, then while creating the sub organization at + SUB1 level, the parent org should be given as ABC.SUB1 + */ + function addSubOrg(string calldata _pOrgId, string calldata _orgId, + string calldata _enodeId, address _caller) external onlyInterface + orgExists(_pOrgId) orgAdmin(_caller, _pOrgId) { + orgManager.addSubOrg(_pOrgId, _orgId); + string memory pOrgId = string(abi.encode(_pOrgId, ".", _orgId)); + if (bytes(_enodeId).length > 0) { + nodeManager.addOrgNode(_enodeId, pOrgId); + } + } + + /** @notice function to update the org status. it updates the org status + and adds a voting item for network admins to approve + * @param _orgId unique id of the organization + * @param _action 1 for suspending an org and 2 for revoke of suspension + */ + function updateOrgStatus(string calldata _orgId, uint256 _action, address _caller) + external onlyInterface networkAdmin(_caller) { + uint256 pendingOp; + pendingOp = orgManager.updateOrg(_orgId, _action); + voterManager.addVotingItem(adminOrg, _orgId, "", address(0), pendingOp); + } + + /** @notice function to approve org status change. the org status is + changed once the majority votes are received from network + admin accounts. + * @param _orgId unique id for the sub organization + * @param _action 1 for suspending an org and 2 for revoke of suspension + */ + function approveOrgStatus(string calldata _orgId, uint256 _action, address _caller) + external onlyInterface networkAdmin(_caller) { + require((_action == 1 || _action == 2), "Operation not allowed"); + uint256 pendingOp; + uint256 orgStatus; + if (_action == 1) { + pendingOp = 2; + orgStatus = 3; + } + else if (_action == 2) { + pendingOp = 3; + orgStatus = 5; + } + require(_checkOrgStatus(_orgId, orgStatus) == true, "operation not allowed"); + if ((processVote(adminOrg, _caller, pendingOp))) { + orgManager.approveOrgStatusUpdate(_orgId, _action); + } + } + + // Role related functions + + /** @notice function to add new role definition to an organization + can be executed by the org admin account only + * @param _roleId unique id for the role + * @param _orgId unique id of the organization to which the role belongs + * @param _access account access type allowed for the role + * @param _voter bool indicates if the role is voter role or not + * @param _admin bool indicates if the role is an admin role + * @dev account access type can have of the following four values: + 0 - Read only + 1 - Transact access + 2 - Contract deployment access. Can transact as well + 3 - Full access + */ + function addNewRole(string calldata _roleId, string calldata _orgId, + uint256 _access, bool _voter, bool _admin, address _caller) external + onlyInterface orgApproved(_orgId) orgAdmin(_caller, _orgId) { + //add new roles can be created by org admins only + roleManager.addRole(_roleId, _orgId, _access, _voter, _admin); + } + + /** @notice function to remove a role definition from an organization + can be executed by the org admin account only + * @param _roleId unique id for the role + * @param _orgId unique id of the organization to which the role belongs + */ + function removeRole(string calldata _roleId, string calldata _orgId, + address _caller) external onlyInterface orgApproved(_orgId) + orgAdmin(_caller, _orgId) { + require(((keccak256(abi.encode(_roleId)) != keccak256(abi.encode(adminRole))) && + (keccak256(abi.encode(_roleId)) != keccak256(abi.encode(orgAdminRole)))), + "admin roles cannot be removed"); + roleManager.removeRole(_roleId, _orgId); + } + + // Account related functions + /** @notice function to assign network admin/org admin role to an account + this can be executed by network admin accounts only. it assigns + the role to the accounts and creates voting record for network + admin accounts + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + * @param _roleId role id to be assigned to the account + */ + function assignAdminRole(string calldata _orgId, address _account, + string calldata _roleId, address _caller) external + onlyInterface orgExists(_orgId) networkAdmin(_caller) { + accountManager.assignAdminRole(_account, _orgId, _roleId, 1); + //add voting item + voterManager.addVotingItem(adminOrg, _orgId, "", _account, 4); + } + + /** @notice function to approve network admin/org admin role assigment + this can be executed by network admin accounts only. + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + */ + function approveAdminRole(string calldata _orgId, address _account, + address _caller) external onlyInterface networkAdmin(_caller) { + if ((processVote(adminOrg, _caller, 4))) { + (bool ret, address account) = accountManager.removeExistingAdmin(_orgId); + if (ret) { + updateVoterList(adminOrg, account, false); + } + bool ret1 = accountManager.addNewAdmin(_orgId, _account); + if (ret1) { + updateVoterList(adminOrg, _account, true); + } + } + } + + /** @notice function to update account status. can be executed by org admin + account only. + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + * @param _action 1-suspend 2-activate back 3-blacklist + */ + function updateAccountStatus(string calldata _orgId, address _account, + uint256 _action, address _caller) external onlyInterface + orgAdmin(_caller, _orgId) { + // ensure that the action passed to this call is proper and is not + // called with action 4 and 5 which are actions for blacklisted account + // recovery + require((_action == 1 || _action == 2 || _action == 3), + "invalid action. operation not allowed"); + accountManager.updateAccountStatus(_orgId, _account, _action); + } + + // Node related functions + + /** @notice function to add a new node to the organization. can be invoked + org admin account only + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + */ + function addNode(string calldata _orgId, string calldata _enodeId, address _caller) + external onlyInterface orgApproved(_orgId) orgAdmin(_caller, _orgId) { + // check that the node is not part of another org + nodeManager.addOrgNode(_enodeId, _orgId); + } + + /** @notice function to update node status. can be invoked by org admin + account only + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + * @param _action 1-deactivate, 2-activate back, 3-blacklist the node + */ + function updateNodeStatus(string calldata _orgId, string calldata _enodeId, + uint256 _action, address _caller) external onlyInterface + orgAdmin(_caller, _orgId) { + // ensure that the action passed to this call is proper and is not + // called with action 4 and 5 which are actions for blacklisted node + // recovery + require((_action == 1 || _action == 2 || _action == 3), + "invalid action. operation not allowed"); + nodeManager.updateNodeStatus(_enodeId, _orgId, _action); + } + + /** @notice function to initiate blacklisted nodes recovery. this can be + invoked by an network admin account only + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + * @dev this function creates a voting record for other network admins to + approve the operation. The recovery is complete only after majority voting + */ + function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId, + address _caller) external onlyInterface networkAdmin(_caller) { + // update the node status as recovery initiated. action for this is 4 + nodeManager.updateNodeStatus(_enodeId, _orgId, 4); + + // add a voting record with pending op of 5 which corresponds to blacklisted node + // recovery + voterManager.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 5); + } + + /** @notice function to initiate blacklisted nodes recovery. this can be + invoked by an network admin account only + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + * @dev this function creates a voting record for other network admins to + approve the operation. The recovery is complete only after majority voting + */ + function approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId, + address _caller) external onlyInterface networkAdmin(_caller) { + // check if majority votes are received. pending op type is passed as 5 + // which stands for black listed node recovery + if ((processVote(adminOrg, _caller, 5))) { + // update the node back to active + nodeManager.updateNodeStatus(_enodeId, _orgId, 5); + } + } + + /** @notice function to initaite blacklisted nodes recovery. this can be + invoked by an network admin account only + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id being dded to the org + * @dev this function creates a voting record for other network admins to + approve the operation. The recovery is complete only after majority voting + */ + function startBlacklistedAccountRecovery(string calldata _orgId, address _account, + address _caller) external onlyInterface networkAdmin(_caller) { + // update the account status as recovery initiated. action for this is 4 + accountManager.updateAccountStatus(_orgId, _account, 4); + // add a voting record with pending op of 5 which corresponds to blacklisted node + // recovery + voterManager.addVotingItem(adminOrg, _orgId, "", _account, 6); + } + + /** @notice function to initaite blacklisted nodes recovery. this can be + invoked by an network admin account only + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id being dded to the org + * @dev this function creates a voting record for other network admins to + approve the operation. The recovery is complete only after majority voting + */ + function approveBlacklistedAccountRecovery(string calldata _orgId, address _account, + address _caller) external onlyInterface networkAdmin(_caller) { + // check if majority votes are received. pending op type is passed as 6 + // which stands for black listed account recovery + if ((processVote(adminOrg, _caller, 6))) { + // update the node back to active + accountManager.updateAccountStatus(_orgId, _account, 5); + } + } + + /** @notice function to fetch network boot status + * @return bool network boot status + */ + function getNetworkBootStatus() external view + returns (bool){ + return networkBoot; + } + + /** @notice function to fetch detail of any pending approval activities + for network admin organization + * @param _orgId unique id of the organization to which the account belongs + */ + function getPendingOp(string calldata _orgId) external view + returns (string memory, string memory, address, uint256){ + return voterManager.getPendingOpDetails(_orgId); + } + + /** @notice function to assigns a role id to the account given account + can be executed by org admin account only + * @param _account account id + * @param _orgId organization id to which the account belongs + * @param _roleId role id to be assigned to the account + */ + function assignAccountRole(address _account, string memory _orgId, + string memory _roleId, address _caller) public + onlyInterface + orgAdmin(_caller, _orgId) + orgApproved(_orgId) { + require(validateAccount(_account, _orgId) == true, "operation cannot be performed"); + require(_roleExists(_roleId, _orgId) == true, "role does not exists"); + bool admin = roleManager.isAdminRole(_roleId, _orgId, _getUltimateParent(_orgId)); + accountManager.assignAccountRole(_account, _orgId, _roleId, admin); + } + + /** @notice function to check if passed account is an network admin account + * @param _account account id + * @return true/false + */ + function isNetworkAdmin(address _account) public view + returns (bool){ + return (keccak256(abi.encode(accountManager.getAccountRole(_account))) == keccak256(abi.encode(adminRole))); + } + + /** @notice function to check if passed account is an org admin account + * @param _account account id + * @param _orgId organization id + * @return true/false + */ + function isOrgAdmin(address _account, string memory _orgId) public view + returns (bool){ + if (accountManager.checkOrgAdmin(_account, _orgId, _getUltimateParent(_orgId))) { + return true; + } + return roleManager.isAdminRole(accountManager.getAccountRole(_account), _orgId, + _getUltimateParent(_orgId)); + } + + /** @notice function to validate the account for access change operation + * @param _account account id + * @param _orgId organization id + * @return true/false + */ + function validateAccount(address _account, string memory _orgId) public view + returns (bool){ + return (accountManager.validateAccount(_account, _orgId)); + } + + /** @notice function to update the voter list at network level. this will + be called whenever an account is assigned a network admin role + or an account having network admin role is being assigned + different role + * @param _orgId org id to which the account belongs + * @param _account account which needs to be added/removed as voter + * @param _add bool indicating if its an add or delete operation + */ + function updateVoterList(string memory _orgId, address _account, bool _add) internal { + if (_add) { + voterManager.addVoter(_orgId, _account); + } + else { + voterManager.deleteVoter(_orgId, _account); + } + } + + /** @notice whenever a network admin account votes on a pending item, this + function processes the vote. + * @param _orgId org id of the caller + * @param _caller account which approving the operation + * @param _pendingOp operation for which the approval is being done + * @dev the list of pending ops are managed in voter manager contract + */ + function processVote(string memory _orgId, address _caller, uint256 _pendingOp) internal + returns (bool){ + return voterManager.processVote(_orgId, _caller, _pendingOp); + } + + /** @notice returns various permissions policy related parameters + * @return adminOrg admin org id + * @return adminRole default network admin role + * @return orgAdminRole default org admin role + * @return networkBoot network boot status + */ + function getPolicyDetails() external view + returns (string memory, string memory, string memory, bool){ + return (adminOrg, adminRole, orgAdminRole, networkBoot); + } + + /** @notice checks if the passed org exists or not + * @param _orgId org id + * @return true/false + */ + function _checkOrgExists(string memory _orgId) internal view + returns (bool){ + return orgManager.checkOrgExists(_orgId); + } + + /** @notice checks if the passed org is in approved status + * @param _orgId org id + * @return true/false + */ + function checkOrgApproved(string memory _orgId) internal view + returns (bool){ + return orgManager.checkOrgStatus(_orgId, 2); + } + + /** @notice checks if the passed org is in the status passed + * @param _orgId org id + * @param _status status to be checked for + * @return true/false + */ + function _checkOrgStatus(string memory _orgId, uint256 _status) internal view + returns (bool){ + return orgManager.checkOrgStatus(_orgId, _status); + } + + /** @notice checks if org admin account exists for the passed org id + * @param _orgId org id + * @return true/false + */ + function _checkOrgAdminExists(string memory _orgId) internal view + returns (bool){ + return accountManager.orgAdminExists(_orgId); + } + + /** @notice checks if role id exists for the passed org_id + * @param _roleId role id + * @param _orgId org id + * @return true/false + */ + function _roleExists(string memory _roleId, string memory _orgId) internal view + returns (bool){ + return roleManager.roleExists(_roleId, _orgId, _getUltimateParent(_orgId)); + } + + /** @notice checks if the role id for the org is a voter role + * @param _roleId role id + * @param _orgId org id + * @return true/false + */ + function _isVoterRole(string memory _roleId, string memory _orgId) internal view + returns (bool){ + return roleManager.isVoterRole(_roleId, _orgId, _getUltimateParent(_orgId)); + } + + /** @notice returns the ultimate parent for a given org id + * @param _orgId org id + * @return ultimate parent org id + */ + function _getUltimateParent(string memory _orgId) internal view + returns (string memory){ + return orgManager.getUltimateParent(_orgId); + } + +} \ No newline at end of file diff --git a/permission/contract/PermissionsInterface.sol b/permission/contract/PermissionsInterface.sol new file mode 100644 index 0000000000..d903adf401 --- /dev/null +++ b/permission/contract/PermissionsInterface.sol @@ -0,0 +1,302 @@ +pragma solidity ^0.5.3; + +import "./PermissionsImplementation.sol"; +import "./PermissionsUpgradable.sol"; + +/** @title Permissions Interface Contract + * @notice This contract is the interface for permissions implementation + contract. for any call, it forwards the call to the implementation + contract + */ +contract PermissionsInterface { + PermissionsImplementation private permImplementation; + PermissionsUpgradable private permUpgradable; + address private permImplUpgradeable; + + /** @notice constructor + * @param _permImplUpgradeable permissions upgradable contract address + */ + constructor(address _permImplUpgradeable) public { + permImplUpgradeable = _permImplUpgradeable; + } + + /** @notice confirms that the caller is the address of upgradable + contract + */ + modifier onlyUpgradeable { + require(msg.sender == permImplUpgradeable, "invalid caller"); + _; + } + + /** @notice interface for setting the permissions policy in implementation + * @param _nwAdminOrg network admin organization id + * @param _nwAdminRole default network admin role id + * @param _oAdminRole default organization admin role id + */ + function setPolicy(string calldata _nwAdminOrg, string calldata _nwAdminRole, + string calldata _oAdminRole) external { + permImplementation.setPolicy(_nwAdminOrg, _nwAdminRole, _oAdminRole); + } + + /** @notice interface to initializes the breadth and depth values for + sub organization management + * @param _breadth controls the number of sub org a parent org can have + * @param _depth controls the depth of nesting allowed for sub orgs + */ + function init(uint256 _breadth, uint256 _depth) external { + permImplementation.init(_breadth, _depth); + } + + /** @notice interface to add new node to an admin organization + * @param _enodeId full enode id of the node to be added + */ + function addAdminNode(string calldata _enodeId) external { + permImplementation.addAdminNode(_enodeId); + } + + /** @notice interface to add accounts to an admin organization + * @param _acct account address to be added + */ + function addAdminAccount(address _acct) external { + permImplementation.addAdminAccount(_acct); + } + + /** @notice interface to update network boot up status + * @return bool true or false + */ + function updateNetworkBootStatus() external + returns (bool) + { + return permImplementation.updateNetworkBootStatus(); + } + + /** @notice interface to fetch network boot status + * @return bool network boot status + */ + function getNetworkBootStatus() external view returns (bool){ + return permImplementation.getNetworkBootStatus(); + } + + /** @notice interface to add a new organization to the network + * @param _orgId unique organization id + * @param _enodeId full enode id linked to the organization + * @param _account account id. this will have the org admin privileges + */ + function addOrg(string calldata _orgId, string calldata _enodeId, + address _account) external { + permImplementation.addOrg(_orgId, _enodeId, _account, msg.sender); + } + + /** @notice interface to approve a newly added organization + * @param _orgId unique organization id + * @param _enodeId full enode id linked to the organization + * @param _account account id this will have the org admin privileges + */ + function approveOrg(string calldata _orgId, string calldata _enodeId, + address _account) external { + permImplementation.approveOrg(_orgId, _enodeId, _account, msg.sender); + } + + /** @notice interface to add sub org under an org + * @param _pOrgId parent org id under which the sub org is being added + * @param _orgId unique id for the sub organization + * @param _enodeId full enode id linked to the sjb organization + */ + function addSubOrg(string calldata _pOrgId, string calldata _orgId, + string calldata _enodeId) external { + permImplementation.addSubOrg(_pOrgId, _orgId, _enodeId, msg.sender); + } + + /** @notice interface to update the org status + * @param _orgId unique id of the organization + * @param _action 1 for suspending an org and 2 for revoke of suspension + */ + function updateOrgStatus(string calldata _orgId, uint256 _action) external { + permImplementation.updateOrgStatus(_orgId, _action, msg.sender); + } + + /** @notice interface to approve org status change + * @param _orgId unique id for the sub organization + * @param _action 1 for suspending an org and 2 for revoke of suspension + */ + function approveOrgStatus(string calldata _orgId, uint256 _action) external { + permImplementation.approveOrgStatus(_orgId, _action, msg.sender); + } + + /** @notice interface to add a new role definition to an organization + * @param _roleId unique id for the role + * @param _orgId unique id of the organization to which the role belongs + * @param _access account access type for the role + * @param _voter bool indicates if the role is voter role or not + * @param _admin bool indicates if the role is an admin role + * @dev account access type can have of the following four values: + 0 - Read only + 1 - Transact access + 2 - Contract deployment access. Can transact as well + 3 - Full access + */ + function addNewRole(string calldata _roleId, string calldata _orgId, + uint256 _access, bool _voter, bool _admin) external { + permImplementation.addNewRole(_roleId, _orgId, _access, _voter, _admin, msg.sender); + } + + /** @notice interface to remove a role definition from an organization + * @param _roleId unique id for the role + * @param _orgId unique id of the organization to which the role belongs + */ + function removeRole(string calldata _roleId, string calldata _orgId) external { + permImplementation.removeRole(_roleId, _orgId, msg.sender); + } + + /** @notice interface to assign network admin/org admin role to an account + this can be executed by network admin accounts only + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + * @param _roleId role id to be assigned to the account + */ + function assignAdminRole(string calldata _orgId, address _account, + string calldata _roleId) external { + permImplementation.assignAdminRole(_orgId, _account, _roleId, msg.sender); + + } + /** @notice interface to approve network admin/org admin role assigment + this can be executed by network admin accounts only + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + */ + function approveAdminRole(string calldata _orgId, address _account) external { + permImplementation.approveAdminRole(_orgId, _account, msg.sender); + + } + + /** @notice interface to update account status + this can be executed by org admin accounts only + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id + * @param _action 1-suspending 2-activating back 3-blacklisting + */ + function updateAccountStatus(string calldata _orgId, address _account, + uint256 _action) external { + permImplementation.updateAccountStatus(_orgId, _account, _action, msg.sender); + } + + /** @notice interface to add a new node to the organization + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + */ + function addNode(string calldata _orgId, string calldata _enodeId) external { + permImplementation.addNode(_orgId, _enodeId, msg.sender); + + } + + /** @notice interface to update node status + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being dded to the org + * @param _action 1-deactivate, 2-activate back, 3-blacklist the node + */ + function updateNodeStatus(string calldata _orgId, string calldata _enodeId, + uint256 _action) external { + permImplementation.updateNodeStatus(_orgId, _enodeId, _action, msg.sender); + } + + /** @notice interface to initiate blacklisted node recovery + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being recovered + */ + function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId) + external { + permImplementation.startBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender); + } + + /** @notice interface to approve blacklisted node recoevry + * @param _orgId unique id of the organization to which the account belongs + * @param _enodeId full enode id being recovered + */ + function approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId) + external { + permImplementation.approveBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender); + } + + /** @notice interface to initiate blacklisted account recovery + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id being recovered + */ + function startBlacklistedAccountRecovery(string calldata _orgId, address _account) + external { + permImplementation.startBlacklistedAccountRecovery(_orgId, _account, msg.sender); + } + + /** @notice interface to approve blacklisted node recovery + * @param _orgId unique id of the organization to which the account belongs + * @param _account account id being recovered + */ + function approveBlacklistedAccountRecovery(string calldata _orgId, address _account) + external { + permImplementation.approveBlacklistedAccountRecovery(_orgId, _account, msg.sender); + } + + /** @notice interface to fetch detail of any pending approval activities + for network admin organization + * @param _orgId unique id of the organization to which the account belongs + */ + function getPendingOp(string calldata _orgId) external view + returns (string memory, string memory, address, uint256) { + return permImplementation.getPendingOp(_orgId); + } + + /** @notice sets the permissions implementation contract address + can be called from upgradable contract only + * @param _permImplementation permissions implementation contract address + */ + function setPermImplementation(address _permImplementation) external + onlyUpgradeable { + permImplementation = PermissionsImplementation(_permImplementation); + } + + /** @notice returns the address of permissions implementation contract + * @return permissions implementation contract address + */ + function getPermissionsImpl() external view returns (address) { + return address(permImplementation); + } + + /** @notice interface to assigns a role id to the account give + * @param _account account id + * @param _orgId organization id to which the account belongs + * @param _roleId role id to be assigned to the account + */ + function assignAccountRole(address _account, string calldata _orgId, + string calldata _roleId) external { + permImplementation.assignAccountRole(_account, _orgId, _roleId, msg.sender); + + } + + /** @notice interface to check if passed account is an network admin account + * @param _account account id + * @return true/false + */ + function isNetworkAdmin(address _account) external view returns (bool) { + return permImplementation.isNetworkAdmin(_account); + } + + /** @notice interface to check if passed account is an org admin account + * @param _account account id + * @param _orgId organization id + * @return true/false + */ + function isOrgAdmin(address _account, string calldata _orgId) + external view returns (bool) { + return permImplementation.isOrgAdmin(_account, _orgId); + } + + /** @notice interface to validate the account for access change operation + * @param _account account id + * @param _orgId organization id + * @return true/false + */ + function validateAccount(address _account, string calldata _orgId) + external view returns (bool) { + return permImplementation.validateAccount(_account, _orgId); + } + +} \ No newline at end of file diff --git a/permission/contract/PermissionsUpgradable.sol b/permission/contract/PermissionsUpgradable.sol new file mode 100644 index 0000000000..5adafcc7d5 --- /dev/null +++ b/permission/contract/PermissionsUpgradable.sol @@ -0,0 +1,103 @@ +pragma solidity ^0.5.3; + +import "./PermissionsInterface.sol"; + +/** @title Permissions Upgradable Contract + * @notice This contract holds the address of current permissions implementation + contract. The contract is owned by a guardian account. Only the + guardian account can change the implementation contract address as + business needs. + */ +contract PermissionsUpgradable { + + address private guardian; + address private permImpl; + address private permInterface; + // initDone ensures that init can be called only once + bool private initDone; + + /** @notice constructor + * @param _guardian account address + */ + constructor (address _guardian) public{ + guardian = _guardian; + initDone = false; + } + + /** @notice confirms that the caller is the guardian account + */ + modifier onlyGuardian { + require(msg.sender == guardian, "invalid caller"); + _; + } + + /** @notice executed by guardian. Links interface and implementation contract + addresses. Can be executed by guardian account only + * @param _permInterface permissions interface contract address + * @param _permImpl implementation contract address + */ + function init(address _permInterface, address _permImpl) external + onlyGuardian { + require(!initDone, "can be executed only once"); + permImpl = _permImpl; + permInterface = _permInterface; + _setImpl(permImpl); + initDone = true; + } + + /** @notice changes the implementation contract address to the new address + address passed. Can be executed by guardian account only + * @param _proposedImpl address of the new permissions implementation contract + */ + function confirmImplChange(address _proposedImpl) public + onlyGuardian { + // The policy details needs to be carried forward from existing + // implementation to new. So first these are read from existing + // implementation and then updated in new implementation + (string memory adminOrg, string memory adminRole, string memory orgAdminRole, bool bootStatus) = PermissionsImplementation(permImpl).getPolicyDetails(); + _setPolicy(_proposedImpl, adminOrg, adminRole, orgAdminRole, bootStatus); + permImpl = _proposedImpl; + _setImpl(permImpl); + } + + /** @notice function to fetch the guardian account address + * @return _guardian guardian account address + */ + function getGuardian() public view returns (address) { + return guardian; + } + + /** @notice function to fetch the current implementation address + * @return permissions implementation contract address + */ + function getPermImpl() public view returns (address) { + return permImpl; + } + /** @notice function to fetch the interface address + * @return permissions interface contract address + */ + function getPermInterface() public view returns (address) { + return permInterface; + } + + /** @notice function to set the permissions policy details in the + permissions implementation contract + * @param _permImpl permissions implementation contract address + * @param _adminOrg name of admin organization + * @param _adminRole name of the admin role + * @param _orgAdminRole name of default organization admin role + * @param _bootStatus network boot status + */ + function _setPolicy(address _permImpl, string memory _adminOrg, string memory _adminRole, string memory _orgAdminRole, bool _bootStatus) private { + PermissionsImplementation(_permImpl).setMigrationPolicy(_adminOrg, _adminRole, _orgAdminRole, _bootStatus); + } + + /** @notice function to set the permissions implementation contract address + in the permissions interface contract + * @param _permImpl permissions implementation contract address + */ + function _setImpl(address _permImpl) private { + PermissionsInterface(permInterface).setPermImplementation(_permImpl); + } + +} \ No newline at end of file diff --git a/permission/contract/RoleManager.sol b/permission/contract/RoleManager.sol new file mode 100644 index 0000000000..c46a0209af --- /dev/null +++ b/permission/contract/RoleManager.sol @@ -0,0 +1,197 @@ +pragma solidity ^0.5.3; + +import "./PermissionsUpgradable.sol"; +/** @title Role manager contract + * @notice This contract holds implementation logic for all role management + functionality. This can be called only by the implementation + contract only. there are few view functions exposed as public and + can be called directly. these are invoked by quorum for populating + permissions data in cache + */ +contract RoleManager { + PermissionsUpgradable private permUpgradable; + + struct RoleDetails { + string roleId; + string orgId; + uint256 baseAccess; + bool isVoter; + bool isAdmin; + bool active; + } + + RoleDetails[] private roleList; + mapping(bytes32 => uint256) private roleIndex; + uint256 private numberOfRoles; + + event RoleCreated(string _roleId, string _orgId, uint256 _baseAccess, + bool _isVoter, bool _isAdmin); + event RoleRevoked(string _roleId, string _orgId); + + /** @notice confirms that the caller is the address of implementation + contract + */ + modifier onlyImplementation { + require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); + _; + } + + /** @notice constructor. sets the permissions upgradable address + */ + constructor (address _permUpgradable) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + } + + /** @notice function to add a new role definition to an organization + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + * @param _baseAccess - 0-ReadOnly, 1-Transact, 2-ContractDeply, 3- Full + * @param _isVoter - bool to indicate if voter role or not + * @param _isAdmin - bool to indicate if admin role or not + * @dev base access can have any of the following values: + 0 - Read only + 1 - Transact only + 2 - Contract deploy. can transact as well + 3 - Full access + */ + function addRole(string memory _roleId, string memory _orgId, uint256 _baseAccess, + bool _isVoter, bool _isAdmin) public onlyImplementation { + // Check if account already exists + require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] == 0, "role exists for the org"); + numberOfRoles ++; + roleIndex[keccak256(abi.encode(_roleId, _orgId))] = numberOfRoles; + roleList.push(RoleDetails(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin, true)); + emit RoleCreated(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin); + + } + + /** @notice function to remove an existing role definition from an organization + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + */ + function removeRole(string calldata _roleId, string calldata _orgId) external + onlyImplementation { + require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0, "role does not exist"); + uint256 rIndex = _getRoleIndex(_roleId, _orgId); + roleList[rIndex].active = false; + emit RoleRevoked(_roleId, _orgId); + } + + /** @notice checks if the role is a voter role or not + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + * @param _ultParent - master org id + * @return true or false + * @dev checks for the role existence in the passed org and master org + */ + function isVoterRole(string calldata _roleId, string calldata _orgId, + string calldata _ultParent) external view onlyImplementation returns (bool){ + if (!(roleExists(_roleId, _orgId, _ultParent))) { + return false; + } + uint256 rIndex; + if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { + rIndex = _getRoleIndex(_roleId, _orgId); + } + else { + rIndex = _getRoleIndex(_roleId, _ultParent); + } + return (roleList[rIndex].active && roleList[rIndex].isVoter); + } + + /** @notice checks if the role is an admin role or not + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + * @param _ultParent - master org id + * @return true or false + * @dev checks for the role existence in the passed org and master org + */ + function isAdminRole(string calldata _roleId, string calldata _orgId, + string calldata _ultParent) external view onlyImplementation returns (bool){ + if (!(roleExists(_roleId, _orgId, _ultParent))) { + return false; + } + uint256 rIndex; + if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { + rIndex = _getRoleIndex(_roleId, _orgId); + } + else { + rIndex = _getRoleIndex(_roleId, _ultParent); + } + return (roleList[rIndex].active && roleList[rIndex].isAdmin); + } + + /** @notice returns the role details for a passed role id and org + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + * @return role id + * @return org id + * @return access type + * @return bool to indicate if the role is a voter role + * @return bool to indicate if the role is active + */ + function getRoleDetails(string calldata _roleId, string calldata _orgId) + external view returns (string memory roleId, string memory orgId, + uint256 accessType, bool voter, bool admin, bool active) { + if (!(roleExists(_roleId, _orgId, ""))) { + return (_roleId, "", 0, false, false, false); + } + uint256 rIndex = _getRoleIndex(_roleId, _orgId); + return (roleList[rIndex].roleId, roleList[rIndex].orgId, + roleList[rIndex].baseAccess, roleList[rIndex].isVoter, + roleList[rIndex].isAdmin, roleList[rIndex].active); + } + + /** @notice returns the role details for a passed role index + * @param _rIndex - unique identifier for the role being added + * @return role id + * @return org id + * @return access type + * @return bool to indicate if the role is a voter role + * @return bool to indicate if the role is active + */ + function getRoleDetailsFromIndex(uint256 _rIndex) external view returns + (string memory roleId, string memory orgId, uint256 accessType, + bool voter, bool admin, bool active) { + return (roleList[_rIndex].roleId, roleList[_rIndex].orgId, + roleList[_rIndex].baseAccess, roleList[_rIndex].isVoter, + roleList[_rIndex].isAdmin, roleList[_rIndex].active); + } + + /** @notice returns the total number of roles in the network + * @return total number of roles + */ + function getNumberOfRoles() external view returns (uint256) { + return roleList.length; + } + + /** @notice checks if the role exists for the given org or master org + * @param _roleId - unique identifier for the role being added + * @param _orgId - org id to which the role belongs + * @param _ultParent - master org id + * @return true or false + */ + function roleExists(string memory _roleId, string memory _orgId, + string memory _ultParent) public view returns (bool) { + uint256 id; + if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { + id = _getRoleIndex(_roleId, _orgId); + return roleList[id].active; + } + else if (roleIndex[keccak256(abi.encode(_roleId, _ultParent))] != 0) { + id = _getRoleIndex(_roleId, _ultParent); + return roleList[id].active; + } + return false; + } + + /** @notice returns the role index based on role id and org id + * @param _roleId - role id + * @param _orgId - org id + * @return role index + */ + function _getRoleIndex(string memory _roleId, string memory _orgId) + internal view returns (uint256) { + return roleIndex[keccak256(abi.encode(_roleId, _orgId))] - 1; + } +} diff --git a/permission/contract/VoterManager.sol b/permission/contract/VoterManager.sol new file mode 100644 index 0000000000..437a8f09c5 --- /dev/null +++ b/permission/contract/VoterManager.sol @@ -0,0 +1,250 @@ +pragma solidity ^0.5.3; + +import "./PermissionsUpgradable.sol"; + +/** @title Voter manager contract + * @notice This contract holds implementation logic for all account voter and + voting functionality. This can be called only by the implementation + contract only. there are few view functions exposed as public and + can be called directly. these are invoked by quorum for populating + permissions data in cache + * @dev each voting record has an attribute operation type (opType) + which denotes the activity type which is pending approval. This can + have the following values: + 0 - None - indicates no pending records for the org + 1 - New org add activity + 2 - Org suspension activity + 3 - Revoke of org suspension + 4 - Assigning admin role for a new account + 5 - Blacklisted node recovery + 6 - Blacklisted account recovery + */ +contract VoterManager { + PermissionsUpgradable private permUpgradable; + struct PendingOpDetails { + string orgId; + string enodeId; + address account; + uint256 opType; + } + + struct Voter { + address vAccount; + bool active; + } + + struct OrgVoterDetails { + string orgId; + uint256 voterCount; + uint256 validVoterCount; + uint256 voteCount; + PendingOpDetails pendingOp; + Voter [] voterList; + mapping(address => uint256) voterIndex; + mapping(uint256 => mapping(address => bool)) votingStatus; + } + + OrgVoterDetails [] private orgVoterList; + mapping(bytes32 => uint256) private VoterOrgIndex; + uint256 private orgNum = 0; + + // events related to managing voting accounts for the org + event VoterAdded(string _orgId, address _vAccount); + event VoterDeleted(string _orgId, address _vAccount); + + event VotingItemAdded(string _orgId); + event VoteProcessed(string _orgId); + + /** @notice confirms that the caller is the address of implementation + contract + */ + modifier onlyImplementation { + require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); + _; + } + + /** @notice checks if account is a valid voter record and belongs to the org + passed + * @param _orgId - org id + * @param _vAccount - voter account passed + */ + modifier voterExists(string memory _orgId, address _vAccount) { + require(_checkVoterExists(_orgId, _vAccount) == true, "must be a voter"); + _; + } + + /** @notice constructor. sets the permissions upgradable address + */ + constructor (address _permUpgradable) public { + permUpgradable = PermissionsUpgradable(_permUpgradable); + } + + /** @notice function to add a new voter account to the organization + * @param _orgId org id + * @param _vAccount - voter account + * @dev voter capability is currently enabled for network level activities + only. voting is not available for org related activities + */ + function addVoter(string calldata _orgId, address _vAccount) external + onlyImplementation { + // check if the org exists + if (VoterOrgIndex[keccak256(abi.encode(_orgId))] == 0) { + orgNum++; + VoterOrgIndex[keccak256(abi.encode(_orgId))] = orgNum; + uint256 id = orgVoterList.length++; + orgVoterList[id].orgId = _orgId; + orgVoterList[id].voterCount = 1; + orgVoterList[id].validVoterCount = 1; + orgVoterList[id].voteCount = 0; + orgVoterList[id].pendingOp.orgId = ""; + orgVoterList[id].pendingOp.enodeId = ""; + orgVoterList[id].pendingOp.account = address(0); + orgVoterList[id].pendingOp.opType = 0; + orgVoterList[id].voterIndex[_vAccount] = orgVoterList[id].voterCount; + orgVoterList[id].voterList.push(Voter(_vAccount, true)); + } + else { + uint256 id = _getVoterOrgIndex(_orgId); + // check if the voter is already present in the list + if (orgVoterList[id].voterIndex[_vAccount] == 0) { + orgVoterList[id].voterCount++; + orgVoterList[id].voterIndex[_vAccount] = orgVoterList[id].voterCount; + orgVoterList[id].voterList.push(Voter(_vAccount, true)); + orgVoterList[id].validVoterCount++; + } + else { + uint256 vid = _getVoterIndex(_orgId, _vAccount); + require(orgVoterList[id].voterList[vid].active != true, "already a voter"); + orgVoterList[id].voterList[vid].active = true; + orgVoterList[id].validVoterCount++; + } + + } + emit VoterAdded(_orgId, _vAccount); + } + + /** @notice function to delete a voter account from the organization + * @param _orgId org id + * @param _vAccount - voter account + * @dev voter capability is currently enabled for network level activities + only. voting is not available for org related activities + */ + function deleteVoter(string calldata _orgId, address _vAccount) external + onlyImplementation + voterExists(_orgId, _vAccount) { + uint256 id = _getVoterOrgIndex(_orgId); + uint256 vId = _getVoterIndex(_orgId, _vAccount); + orgVoterList[id].validVoterCount --; + orgVoterList[id].voterList[vId].active = false; + emit VoterDeleted(_orgId, _vAccount); + } + + /** @notice function to a voting item for network admin accounts to vote + * @param _authOrg org id of the authorizing org. it will be network admin org + * @param _orgId - org id for which the voting record is being created + * @param _enodeId - enode id for which the voting record is being created + * @param _account - account id for which the voting record is being created + * @param _pendingOp - operation for which voting is being done + */ + function addVotingItem(string calldata _authOrg, string calldata _orgId, + string calldata _enodeId, address _account, uint256 _pendingOp) + external onlyImplementation { + // check if anything is pending approval for the org. + // If yes another item cannot be added + require((_checkPendingOp(_authOrg, 0)), + "items pending for approval. new item cannot be added"); + uint256 id = _getVoterOrgIndex(_authOrg); + orgVoterList[id].pendingOp.orgId = _orgId; + orgVoterList[id].pendingOp.enodeId = _enodeId; + orgVoterList[id].pendingOp.account = _account; + orgVoterList[id].pendingOp.opType = _pendingOp; + // initialize vote status for voter accounts + for (uint256 i = 0; i < orgVoterList[id].voterList.length; i++) { + if (orgVoterList[id].voterList[i].active) { + orgVoterList[id].votingStatus[id][orgVoterList[id].voterList[i].vAccount] = false; + } + } + // set vote count to zero + orgVoterList[id].voteCount = 0; + emit VotingItemAdded(_authOrg); + + } + + /** @notice function processing vote of a voter account + * @param _authOrg org id of the authorizing org. it will be network admin org + * @param _vAccount - account id of the voter + * @param _pendingOp - operation which is being approved + * @return success of the voter process. either true or false + */ + function processVote(string calldata _authOrg, address _vAccount, uint256 _pendingOp) + external onlyImplementation voterExists(_authOrg, _vAccount) returns (bool) { + // check something if anything is pending approval + require(_checkPendingOp(_authOrg, _pendingOp) == true, "nothing to approve"); + uint256 id = _getVoterOrgIndex(_authOrg); + // check if vote is already processed + require(orgVoterList[id].votingStatus[id][_vAccount] != true, "cannot double vote"); + orgVoterList[id].voteCount++; + orgVoterList[id].votingStatus[id][_vAccount] = true; + emit VoteProcessed(_authOrg); + if (orgVoterList[id].voteCount > orgVoterList[id].validVoterCount / 2) { + // majority achieved, clean up pending op + orgVoterList[id].pendingOp.orgId = ""; + orgVoterList[id].pendingOp.enodeId = ""; + orgVoterList[id].pendingOp.account = address(0); + orgVoterList[id].pendingOp.opType = 0; + return true; + } + return false; + } + + /** @notice returns the details of any pending operation to be approved + * @param _orgId org id. this will be the org id of network admin org + */ + function getPendingOpDetails(string calldata _orgId) external view + onlyImplementation returns (string memory, string memory, address, uint256){ + uint256 orgIndex = _getVoterOrgIndex(_orgId); + return (orgVoterList[orgIndex].pendingOp.orgId, orgVoterList[orgIndex].pendingOp.enodeId, + orgVoterList[orgIndex].pendingOp.account, orgVoterList[orgIndex].pendingOp.opType); + } + + /** @notice checks if the voter account exists and is linked to the org + * @param _orgId org id + * @param _vAccount voter account id + * @return true or false + */ + function _checkVoterExists(string memory _orgId, address _vAccount) + internal view returns (bool){ + uint256 orgIndex = _getVoterOrgIndex(_orgId); + if (orgVoterList[orgIndex].voterIndex[_vAccount] == 0) { + return false; + } + uint256 voterIndex = _getVoterIndex(_orgId, _vAccount); + return orgVoterList[orgIndex].voterList[voterIndex].active; + } + + /** @notice checks if the pending operation exists or not + * @param _orgId org id + * @param _pendingOp type of operation + * @return true or false + */ + function _checkPendingOp(string memory _orgId, uint256 _pendingOp) + internal view returns (bool){ + return (orgVoterList[_getVoterOrgIndex(_orgId)].pendingOp.opType == _pendingOp); + } + + /** @notice returns the voter account index + */ + function _getVoterIndex(string memory _orgId, address _vAccount) + internal view returns (uint256) { + uint256 orgIndex = _getVoterOrgIndex(_orgId); + return orgVoterList[orgIndex].voterIndex[_vAccount] - 1; + } + + /** @notice returns the org index for the org from voter list + */ + function _getVoterOrgIndex(string memory _orgId) + internal view returns (uint256) { + return VoterOrgIndex[keccak256(abi.encode(_orgId))] - 1; + } + +} diff --git a/permission/contract/gen/AccountManager.abi b/permission/contract/gen/AccountManager.abi new file mode 100644 index 0000000000..7dfbdb8ee1 --- /dev/null +++ b/permission/contract/gen/AccountManager.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"},{"name":"_roleId","type":"string"},{"name":"_adminRole","type":"bool"}],"name":"assignAccountRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"removeExistingAdmin","outputs":[{"name":"voterUpdate","type":"bool"},{"name":"account","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"getAccountDetails","outputs":[{"name":"","type":"address"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfAccounts","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"}],"name":"validateAccount","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"getAccountRole","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_action","type":"uint256"}],"name":"updateAccountStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"orgAdminExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_aIndex","type":"uint256"}],"name":"getAccountDetailsFromIndex","outputs":[{"name":"","type":"address"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"}],"name":"addNewAdmin","outputs":[{"name":"voterUpdate","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nwAdminRole","type":"string"},{"name":"_oAdminRole","type":"string"}],"name":"setDefaults","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"},{"name":"_roleId","type":"string"},{"name":"_status","type":"uint256"}],"name":"assignAdminRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"},{"name":"_ultParent","type":"string"}],"name":"checkOrgAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_account","type":"address"},{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_roleId","type":"string"},{"indexed":false,"name":"_orgAdmin","type":"bool"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"AccountAccessModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_account","type":"address"},{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_roleId","type":"string"},{"indexed":false,"name":"_orgAdmin","type":"bool"}],"name":"AccountAccessRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_account","type":"address"},{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"AccountStatusChanged","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/AccountManager.bin b/permission/contract/gen/AccountManager.bin new file mode 100644 index 0000000000..69c3424090 --- /dev/null +++ b/permission/contract/gen/AccountManager.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50604051602080620048c18339810180604052602081101561003157600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061482e80620000936000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806384b7a84a116100a9578063c214e5e511610083578063c214e5e514610877578063cef7f6af14610928578063e3483a9d146109f6578063e8b42bf414610aee576100ec565b806384b7a84a146105a9578063950145cf1461064c578063b20185681461071f576100ec565b8063143a5604146100f15780631d09dc93146101eb5780632aceb534146102af578063309e36ef1461041d5780636b568d761461043b57806381d66b23146104ec575b600080fd5b6101e96004803603608081101561010757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561014457600080fd5b82018360208201111561015657600080fd5b8035906020019184600183028401116401000000008311171561017857600080fd5b90919293919293908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390803515159060200190929190505050610c78565b005b6102626004803603602081101561020157600080fd5b810190808035906020019064010000000081111561021e57600080fd5b82018360208201111561023057600080fd5b8035906020019184600183028401116401000000008311171561025257600080fd5b9091929391929390505050611157565b60405180831515151581526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6102f1600480360360208110156102c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611823565b604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185815260200184151515158152602001838103835287818151815260200191508051906020019080838360005b8381101561037757808201518184015260208101905061035c565b50505050905090810190601f1680156103a45780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b838110156103dd5780820151818401526020810190506103c2565b50505050905090810190601f16801561040a5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b610425611afe565b6040518082815260200191505060405180910390f35b6104d26004803603604081101561045157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561048e57600080fd5b8201836020820111156104a057600080fd5b803590602001918460018302840111640100000000831117156104c257600080fd5b9091929391929390505050611b0b565b604051808215151515815260200191505060405180910390f35b61052e6004803603602081101561050257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c91565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561056e578082015181840152602081019050610553565b50505050905090810190601f16801561059b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61064a600480360360608110156105bf57600080fd5b81019080803590602001906401000000008111156105dc57600080fd5b8201836020820111156105ee57600080fd5b8035906020019184600183028401116401000000008311171561061057600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e4f565b005b6107056004803603602081101561066257600080fd5b810190808035906020019064010000000081111561067f57600080fd5b82018360208201111561069157600080fd5b803590602001918460018302840111640100000000831117156106b357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612781565b604051808215151515815260200191505060405180910390f35b61074b6004803603602081101561073557600080fd5b8101908080359060200190929190505050612957565b604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185815260200184151515158152602001838103835287818151815260200191508051906020019080838360005b838110156107d15780820151818401526020810190506107b6565b50505050905090810190601f1680156107fe5780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b8381101561083757808201518184015260208101905061081c565b50505050905090810190601f1680156108645780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b61090e6004803603604081101561088d57600080fd5b81019080803590602001906401000000008111156108aa57600080fd5b8201836020820111156108bc57600080fd5b803590602001918460018302840111640100000000831117156108de57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b7a565b604051808215151515815260200191505060405180910390f35b6109f46004803603604081101561093e57600080fd5b810190808035906020019064010000000081111561095b57600080fd5b82018360208201111561096d57600080fd5b8035906020019184600183028401116401000000008311171561098f57600080fd5b9091929391929390803590602001906401000000008111156109b057600080fd5b8201836020820111156109c257600080fd5b803590602001918460018302840111640100000000831117156109e457600080fd5b90919293919293905050506132e3565b005b610aec60048036036080811015610a0c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a4957600080fd5b820183602082011115610a5b57600080fd5b80359060200191846001830284011164010000000083111715610a7d57600080fd5b909192939192939080359060200190640100000000811115610a9e57600080fd5b820183602082011115610ab057600080fd5b80359060200191846001830284011164010000000083111715610ad257600080fd5b90919293919293908035906020019092919050505061346d565b005b610c5e60048036036060811015610b0457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610b4157600080fd5b820183602082011115610b5357600080fd5b80359060200191846001830284011164010000000083111715610b7557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610bd857600080fd5b820183602082011115610bea57600080fd5b80359060200191846001830284011164010000000083111715610c0c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506138c5565b604051808215151515815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610cfb57600080fd5b505afa158015610d0f573d6000803e3d6000fd5b505050506040513d6020811015610d2557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60046040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610e665780601f10610e3b57610100808354040283529160200191610e66565b820191906000526020600020905b815481529060010190602001808311610e4957829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014158015611062575060056040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610f6c5780601f10610f4157610100808354040283529160200191610f6c565b820191906000526020600020905b815481529060010190602001808311610f4f57829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040526040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015611017578082015181840152602081019050610ffc565b50505050905090810190601f1680156110445780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012014155b15156110b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604081526020018061475e6040913960400191505060405180910390fd5b61114f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600285613ebc565b505050505050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156111dd57600080fd5b505afa1580156111f1573d6000803e3d6000fd5b505050506040513d602081101561120757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b61130784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612781565b1561181157600061139c60066000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166143d6565b905060066001828154811015156113af57fe5b90600052602060002090600502016003018190555060006001828154811015156113d557fe5b906000526020600020906005020160040160006101000a81548160ff0219169083151502179055507f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc77660018281548110151561142d57fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018381548110151561146e57fe5b906000526020600020906005020160010160018481548110151561148e57fe5b90600052602060002090600502016002016001858154811015156114ae57fe5b906000526020600020906005020160040160009054906101000a900460ff166001868154811015156114dc57fe5b906000526020600020906005020160030154604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001851515151581526020018481526020018381038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156115bd5780601f10611592576101008083540402835291602001916115bd565b820191906000526020600020905b8154815290600101906020018083116115a057829003601f168201915b50508381038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156116405780601f1061161557610100808354040283529160200191611640565b820191906000526020600020905b81548152906001019060200180831161162357829003601f168201915b505097505050505050505060405180910390a1600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156116e15780601f106116b6576101008083540402835291602001916116e1565b820191906000526020600020905b8154815290600101906020018083116116c457829003601f168201915b5050925050506040516020818303038152906040528051906020012060018281548110151561170c57fe5b906000526020600020906005020160020160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156117a95780601f1061177e576101008083540402835291602001916117a9565b820191906000526020600020905b81548152906001019060200180831161178c57829003601f168201915b50509250505060405160208183030381529060405280519060200120146001828154811015156117d557fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16925092505061181c565b600080809050915091505b9250929050565b60006060806000806000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156118d457856000806040805190810160405280600481526020017f4e4f4e450000000000000000000000000000000000000000000000000000000081525091906020604051908101604052806000815250919081915094509450945094509450611af5565b60006118df876143d6565b90506001818154811015156118f057fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018281548110151561193157fe5b906000526020600020906005020160010160018381548110151561195157fe5b906000526020600020906005020160020160018481548110151561197157fe5b90600052602060002090600502016003015460018581548110151561199257fe5b906000526020600020906005020160040160009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611a465780601f10611a1b57610100808354040283529160200191611a46565b820191906000526020600020905b815481529060010190602001808311611a2957829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ae25780601f10611ab757610100808354040283529160200191611ae2565b820191906000526020600020905b815481529060010190602001808311611ac557829003601f168201915b5050505050925095509550955095509550505b91939590929450565b6000600180549050905090565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611b5d5760019050611c8a565b6000611b68856143d6565b9050838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120600182815481101515611bcc57fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015611c695780601f10611c3e57610100808354040283529160200191611c69565b820191906000526020600020905b815481529060010190602001808311611c4c57829003601f168201915b50509250505060405160208183030381529060405280519060200120149150505b9392505050565b60606000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611d18576040805190810160405280600481526020017f4e4f4e45000000000000000000000000000000000000000000000000000000008152509050611e4a565b6000611d23836143d6565b90506000600182815481101515611d3657fe5b906000526020600020906005020160030154141515611e1057600181815481101515611d5e57fe5b90600052602060002090600502016002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611e035780601f10611dd857610100808354040283529160200191611e03565b820191906000526020600020905b815481529060010190602001808311611de657829003601f168201915b5050505050915050611e4a565b6040805190810160405280600481526020017f4e4f4e45000000000000000000000000000000000000000000000000000000008152509150505b919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611ed257600080fd5b505afa158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611faf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050826000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141515156120ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f6163636f756e7420646f6573206e6f742065786973747300000000000000000081525060200191505060405180910390fd5b816040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156120f15780820151818401526020810190506120d6565b50505050905090810190601f16801561211e5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001206001612144836143d6565b81548110151561215057fe5b906000526020600020906005020160010160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121ed5780601f106121c2576101008083540402835291602001916121ed565b820191906000526020600020905b8154815290600101906020018083116121d057829003601f168201915b5050925050506040516020818303038152906040528051906020012014151561227e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6163636f756e7420696e20646966666572656e74206f7267000000000000000081525060200191505060405180910390fd5b60008311801561228e5750600683105b1515612302576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f696e76616c696420737461747573206368616e6765207265717565737400000081525060200191505060405180910390fd5b600115156123658588888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060206040519081016040528060008152506138c5565b1515141515156123c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806147d26031913960400191505060405180910390fd5b6000600184141561245757600260016123d8876143d6565b8154811015156123e457fe5b90600052602060002090600502016003015414151561244e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260398152602001806146fd6039913960400191505060405180910390fd5b600490506126ac565b60028414156124ec576004600161246d876143d6565b81548110151561247957fe5b9060005260206000209060050201600301541415156124e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806146c1603c913960400191505060405180910390fd5b600290506126ab565b60038414156125825760056001612502876143d6565b81548110151561250e57fe5b90600052602060002090600502016003015414151515612579576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806146896038913960400191505060405180910390fd5b600590506126aa565b60048414156126175760056001612598876143d6565b8154811015156125a457fe5b90600052602060002090600502016003015414151561260e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603481526020018061479e6034913960400191505060405180910390fd5b600790506126a9565b60058414156126a8576007600161262d876143d6565b81548110151561263957fe5b9060005260206000209060050201600301541415156126a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806146516038913960400191505060405180910390fd5b600290505b5b5b5b5b8060016126b8876143d6565b8154811015156126c457fe5b9060005260206000209060050201600301819055507f36b0ea38154dec5e98b6bf928b971a9db5e8cd4b6946350e9e43fb9848c70b2585888884604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018381526020018281038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a150505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff1660066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156127e25780820151818401526020810190506127c7565b50505050905090810190601f16801561280f5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561294d57600060066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156128c05780820151818401526020810190506128a5565b50505050905090810190601f1680156128ed5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600261294482614422565b14915050612952565b600090505b919050565b600060608060008060018681548110151561296e57fe5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166001878154811015156129af57fe5b90600052602060002090600502016001016001888154811015156129cf57fe5b90600052602060002090600502016002016001898154811015156129ef57fe5b90600052602060002090600502016003015460018a815481101515612a1057fe5b906000526020600020906005020160040160009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612ac45780601f10612a9957610100808354040283529160200191612ac4565b820191906000526020600020905b815481529060010190602001808311612aa757829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612b605780601f10612b3557610100808354040283529160200191612b60565b820191906000526020600020905b815481529060010190602001808311612b4357829003601f168201915b505050505092509450945094509450945091939590929450565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015612bff57600080fd5b505afa158015612c13573d6000803e3d6000fd5b505050506040513d6020811015612c2957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6060612ce783611c91565b90506000612cf484614422565b90506000612d01856143d6565b905060056040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612d915780601f10612d6657610100808354040283529160200191612d91565b820191906000526020600020905b815481529060010190602001808311612d7457829003601f168201915b50509250505060405160208183030381529060405280519060200120836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612df1578082015181840152602081019050612dd6565b50505050905090810190601f168015612e1e5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120148015612e465750600182145b15612ef0578460066000898960405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6002600182815481101515612f0157fe5b90600052602060002090600502016003018190555060018082815481101515612f2657fe5b906000526020600020906005020160040160006101000a81548160ff0219169083151502179055507f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc77685600183815481101515612f7f57fe5b9060005260206000209060050201600101600184815481101515612f9f57fe5b9060005260206000209060050201600201600185815481101515612fbf57fe5b906000526020600020906005020160040160009054906101000a900460ff16600186815481101515612fed57fe5b906000526020600020906005020160030154604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001851515151581526020018481526020018381038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130ce5780601f106130a3576101008083540402835291602001916130ce565b820191906000526020600020905b8154815290600101906020018083116130b157829003601f168201915b50508381038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156131515780601f1061312657610100808354040283529160200191613151565b820191906000526020600020905b81548152906001019060200180831161313457829003601f168201915b505097505050505050505060405180910390a1600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156131f25780601f106131c7576101008083540402835291602001916131f2565b820191906000526020600020905b8154815290600101906020018083116131d557829003601f168201915b5050925050506040516020818303038152906040528051906020012060018281548110151561321d57fe5b906000526020600020906005020160020160405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156132ba5780601f1061328f576101008083540402835291602001916132ba565b820191906000526020600020905b81548152906001019060200180831161329d57829003601f168201915b505092505050604051602081830303815290604052805190602001201493505050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561336657600080fd5b505afa15801561337a573d6000803e3d6000fd5b505050506040513d602081101561339057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b8383600491906134549291906144ab565b508181600591906134669291906144ab565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156134f057600080fd5b505afa158015613504573d6000803e3d6000fd5b505050506040513d602081101561351a57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156135cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6005604051602001808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561365b5780601f106136305761010080835404028352916020019161365b565b820191906000526020600020905b81548152906001019060200180831161363e57829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014806137d057506004604051602001808060200182810382528381815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561375f5780601f106137345761010080835404028352916020019161375f565b820191906000526020600020905b81548152906001019060200180831161374257829003601f168201915b50509250505060405160208183030381529060405280519060200120838360405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120145b1515613827576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806147366028913960400191505060405180910390fd5b6138bd8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846001613ebc565b505050505050565b6000600460405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139555780601f1061392a57610100808354040283529160200191613955565b820191906000526020600020905b81548152906001019060200180831161393857829003601f168201915b5050925050506040516020818303038152906040528051906020012061397a85611c91565b6040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156139bd5780820151818401526020810190506139a2565b50505050905090810190601f1680156139ea5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001201415613cd1576000613a16856143d6565b9050836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613a5c578082015181840152602081019050613a41565b50505050905090810190601f168015613a895780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120600182815481101515613ab357fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613b505780601f10613b2557610100808354040283529160200191613b50565b820191906000526020600020905b815481529060010190602001808311613b3357829003601f168201915b505092505050604051602081830303815290604052805190602001201480613cc95750826040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613bb7578082015181840152602081019050613b9c565b50505050905090810190601f168015613be45780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120600182815481101515613c0e57fe5b90600052602060002090600502016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613cab5780601f10613c8057610100808354040283529160200191613cab565b820191906000526020600020905b815481529060010190602001808311613c8e57829003601f168201915b50509250505060405160208183030381529060405280519060200120145b915050613eb5565b8373ffffffffffffffffffffffffffffffffffffffff1660066000856040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613d30578082015181840152602081019050613d15565b50505050905090810190601f168015613d5d5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480613eb257508373ffffffffffffffffffffffffffffffffffffffff1660066000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015613e23578082015181840152602081019050613e08565b50505050905090810190601f168015613e505780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b90505b9392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613f3f57600080fd5b505afa158015613f53573d6000803e3d6000fd5b505050506040513d6020811015613f6957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561401c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000614027866143d6565b90506000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141515614109578360018281548110151561408257fe5b906000526020600020906005020160020190805190602001906140a692919061452b565b50826001828154811015156140b757fe5b906000526020600020906005020160030181905550816001828154811015156140dc57fe5b906000526020600020906005020160040160006101000a81548160ff02191690831515021790555061427d565b600360008154809291906001019190505550600354600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600160a0604051908101604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018781526020018681526020018581526020018415158152509080600181540180825580915050906001820390600052602060002090600502016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190805190602001906142319291906145ab565b50604082015181600201908051906020019061424e9291906145ab565b506060820151816003015560808201518160040160006101000a81548160ff0219169083151502179055505050505b7f68e62a03aeb0a125c2fc869eed72f2fca473680987bdd680c093a534e17cc7768686868587604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200185151515158152602001848152602001838103835287818151815260200191508051906020019080838360005b8381101561432957808201518184015260208101905061430e565b50505050905090810190601f1680156143565780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b8381101561438f578082015181840152602081019050614374565b50505050905090810190601f1680156143bc5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a1505050505050565b60006001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054039050919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561447457600090506144a6565b600061447f836143d6565b905060018181548110151561449057fe5b9060005260206000209060050201600301549150505b919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106144ec57803560ff191683800117855561451a565b8280016001018555821561451a579182015b828111156145195782358255916020019190600101906144fe565b5b509050614527919061462b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061456c57805160ff191683800117855561459a565b8280016001018555821561459a579182015b8281111561459957825182559160200191906001019061457e565b5b5090506145a7919061462b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145ec57805160ff191683800117855561461a565b8280016001018555821561461a579182015b828111156146195782518255916020019190600101906145fe565b5b509050614627919061462b565b5090565b61464d91905b80821115614649576000816000905550600101614631565b5090565b9056fe6163636f756e74207265636f76657279206e6f7420696e697469617465642e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e7420697320616c726561647920626c61636b6c69737465642e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e74206973206e6f7420696e2073757370656e646564207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e656163636f756e74206973206e6f7420696e20616374697665207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e6563616e2062652063616c6c656420746f2061737369676e2061646d696e20726f6c6573206f6e6c7963616e6e6f742062652063616c6c65642066726f2061737369676e696e67206f72672061646d696e20616e64206e6574776f726b2061646d696e20726f6c65736163636f756e74206973206e6f7420626c61636b6c69737465642e206f7065726174696f6e2063616e6e6f7420626520646f6e65737461747573206368616e6765206e6f7420706f737369626c6520666f72206f72672061646d696e206163636f756e7473a165627a7a72305820a534fbde5dac7e84dd47dee87465cfb80f5dc4b2409ed9c4e52bced609423e980029 \ No newline at end of file diff --git a/permission/contract/gen/NodeManager.abi b/permission/contract/gen/NodeManager.abi new file mode 100644 index 0000000000..70e4b62a18 --- /dev/null +++ b/permission/contract/gen/NodeManager.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateNodeStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"enodeId","type":"string"}],"name":"getNodeDetails","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addOrgNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"approveNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeIndex","type":"uint256"}],"name":"getNodeDetailsFromIndex","outputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_nodeStatus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfNodes","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addAdminNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeRecoveryInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_enodeId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"NodeRecoveryCompleted","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/NodeManager.bin b/permission/contract/gen/NodeManager.bin new file mode 100644 index 0000000000..6c8f64a05c --- /dev/null +++ b/permission/contract/gen/NodeManager.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506040516020806131c18339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613130806100916000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c01000000000000000000000000000000000000000000000000000000009004806397c07a9b1161007857806397c07a9b14610483578063a97a44061461059d578063b81c806a1461066b578063e3b09d8414610689576100a5565b80630cc50146146100aa5780633f0e0e47146101825780633f5e1a45146102e757806386bc3652146103b5575b600080fd5b610180600480360360608110156100c057600080fd5b81019080803590602001906401000000008111156100dd57600080fd5b8201836020820111156100ef57600080fd5b8035906020019184600183028401116401000000008311171561011157600080fd5b90919293919293908035906020019064010000000081111561013257600080fd5b82018360208201111561014457600080fd5b8035906020019184600183028401116401000000008311171561016657600080fd5b909192939192939080359060200190929190505050610757565b005b6101f96004803603602081101561019857600080fd5b81019080803590602001906401000000008111156101b557600080fd5b8201836020820111156101c757600080fd5b803590602001918460018302840111640100000000831117156101e957600080fd5b9091929391929390505050611404565b604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b83811015610243578082015181840152602081019050610228565b50505050905090810190601f1680156102705780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156102a957808201518184015260208101905061028e565b50505050905090810190601f1680156102d65780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b6103b3600480360360408110156102fd57600080fd5b810190808035906020019064010000000081111561031a57600080fd5b82018360208201111561032c57600080fd5b8035906020019184600183028401116401000000008311171561034e57600080fd5b90919293919293908035906020019064010000000081111561036f57600080fd5b82018360208201111561038157600080fd5b803590602001918460018302840111640100000000831117156103a357600080fd5b9091929391929390505050611600565b005b610481600480360360408110156103cb57600080fd5b81019080803590602001906401000000008111156103e857600080fd5b8201836020820111156103fa57600080fd5b8035906020019184600183028401116401000000008311171561041c57600080fd5b90919293919293908035906020019064010000000081111561043d57600080fd5b82018360208201111561044f57600080fd5b8035906020019184600183028401116401000000008311171561047157600080fd5b9091929391929390505050611af0565b005b6104af6004803603602081101561049957600080fd5b8101908080359060200190929190505050612159565b604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156104f95780820151818401526020810190506104de565b50505050905090810190601f1680156105265780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561055f578082015181840152602081019050610544565b50505050905090810190601f16801561058c5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b610669600480360360408110156105b357600080fd5b81019080803590602001906401000000008111156105d057600080fd5b8201836020820111156105e257600080fd5b8035906020019184600183028401116401000000008311171561060457600080fd5b90919293919293908035906020019064010000000081111561062557600080fd5b82018360208201111561063757600080fd5b8035906020019184600183028401116401000000008311171561065957600080fd5b9091929391929390505050612304565b005b6106736127f4565b6040518082815260200191505060405180910390f35b6107556004803603604081101561069f57600080fd5b81019080803590602001906401000000008111156106bc57600080fd5b8201836020820111156106ce57600080fd5b803590602001918460018302840111640100000000831117156106f057600080fd5b90919293919293908035906020019064010000000081111561071157600080fd5b82018360208201111561072357600080fd5b8035906020019184600183028401116401000000008311171561074557600080fd5b90919293919293905050506127fe565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156107da57600080fd5b505afa1580156107ee573d6000803e3d6000fd5b505050506040513d602081101561080457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561094657808201518184015260208101905061092b565b50505050905090810190601f1680156109735780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012081526020019081526020016000205414151515610a13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f70617373656420656e6f646520696420646f6573206e6f74206578697374000081525060200191505060405180910390fd5b610aa586868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612cee565b1515610afc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613088602a913960400191505060405180910390fd5b6001821480610b0b5750600282145b80610b165750600382145b80610b215750600482145b80610b2c5750600582145b1515610b83576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806130b26026913960400191505060405180910390fd5b6001821415610d5e576002610bdb87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515610c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60036001610ca188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610cad57fe5b9060005260206000209060030201600201819055507fc6c3720fe673e87bb26e06be713d514278aa94c3939cfe7c64b9bea4d486824a868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fc565b6002821415610f39576003610db687878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60026001610e7c88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610e8857fe5b9060005260206000209060030201600201819055507f49796be3ca168a59c8ae46c75a36a9bb3a84753d3e12a812f93ae010e783b14f868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fb565b60038214156110505760046001610f9388888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b815481101515610f9f57fe5b9060005260206000209060030201600201819055507f4714623279994517c446c8fb72c3fdaca26434da1e2490d3976fe0cd880cfa7a868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113fa565b600482141561122b5760046110a887878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b14151561111d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6005600161116e88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b81548110151561117a57fe5b9060005260206000209060030201600201819055507ffd385c618a1e89d01fb9a21780846793e282e8bc0b60caf6ccb3e422d543fbfb868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a16113f9565b600561127a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b1415156112ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6002600161134088888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b81548110151561134c57fe5b9060005260206000209060030201600201819055507f787d7bc525e7c4658c64e3e456d974a1be21cc196e8162a4bf1337a12cb38dac868686866040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15b5b5b5b505050505050565b60608060008061145786868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b905060018181548110151561146857fe5b906000526020600020906003020160010160018281548110151561148857fe5b90600052602060002090600302016000016001838154811015156114a857fe5b906000526020600020906003020160020154828054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561154f5780601f106115245761010080835404028352916020019161154f565b820191906000526020600020905b81548152906001019060200180831161153257829003601f168201915b50505050509250818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115eb5780601f106115c0576101008083540402835291602001916115eb565b820191906000526020600020905b8154815290600101906020018083116115ce57829003601f168201915b50505050509150935093509350509250925092565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561168357600080fd5b505afa158015611697573d6000803e3d6000fd5b505050506040513d60208110156116ad57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156117ef5780820151818401526020810190506117d4565b50505050905090810190601f16801561181c5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016002815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000019080519060200190611a27929190612fe2565b506020820151816001019080519060200190611a44929190612fe2565b50604082015181600201555050507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611b7357600080fd5b505afa158015611b87573d6000803e3d6000fd5b505050506040513d6020811015611b9d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611c50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015611cdf578082015181840152602081019050611cc4565b50505050905090810190601f168015611d0c5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012081526020019081526020016000205414151515611dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f70617373656420656e6f646520696420646f6573206e6f74206578697374000081525060200191505060405180910390fd5b611e3e85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612cee565b1515611e95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806130d8602d913960400191505060405180910390fd5b6001611ee486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e55565b141515611f59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6e6f7468696e672070656e64696e6720666f7220617070726f76616c0000000081525060200191505060405180910390fd5b6000611fa886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612f37565b90506002600182815481101515611fbb57fe5b9060005260206000209060030201600201819055507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d60018281548110151561200057fe5b906000526020600020906003020160000160018381548110151561202057fe5b90600052602060002090600302016001016040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156120be5780601f10612093576101008083540402835291602001916120be565b820191906000526020600020905b8154815290600101906020018083116120a157829003601f168201915b50508381038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121415780601f1061211657610100808354040283529160200191612141565b820191906000526020600020905b81548152906001019060200180831161212457829003601f168201915b505094505050505060405180910390a1505050505050565b606080600060018481548110151561216d57fe5b906000526020600020906003020160010160018581548110151561218d57fe5b90600052602060002090600302016000016001868154811015156121ad57fe5b906000526020600020906003020160020154828054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156122545780601f1061222957610100808354040283529160200191612254565b820191906000526020600020905b81548152906001019060200180831161223757829003601f168201915b50505050509250818054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156122f05780601f106122c5576101008083540402835291602001916122f0565b820191906000526020600020905b8154815290600101906020018083116122d357829003601f168201915b505050505091509250925092509193909250565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561238757600080fd5b505afa15801561239b573d6000803e3d6000fd5b505050506040513d60208110156123b157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612464576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156124f35780820151818401526020810190506124d8565b50505050905090810190601f1680156125205780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415156125bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508152602001600181525090806001815401808255809150509060018203906000526020600020906003020160009091929091909150600082015181600001908051906020019061272b929190612fe2565b506020820151816001019080519060200190612748929190612fe2565b50604082015181600201555050507fb1a7eec7dd1a516c3132d6d1f770758b19aa34c3a07c138caf662688b7e3556f858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000600354905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561288157600080fd5b505afa158015612895573d6000803e3d6000fd5b505050506040513d60208110156128ab57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561295e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600060026000836040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156129ed5780820151818401526020810190506129d2565b50505050905090810190601f168015612a1a5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054141515612ab9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70617373656420656e6f6465206964206578697374730000000000000000000081525060200191505060405180910390fd5b60036000815480929190600101919050555060035460026000878760405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160606040519081016040528087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020016002815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000019080519060200190612c25929190612fe2565b506020820151816001019080519060200190612c42929190612fe2565b50604082015181600201555050507f0413ce00d5de406d9939003416263a7530eaeb13f9d281c8baeba1601def960d858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000816040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612d34578082015181840152602081019050612d19565b50505050905090810190601f168015612d615780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001206001612d8785612f37565b815481101515612d9357fe5b90600052602060002090600302016001016040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612e305780601f10612e0557610100808354040283529160200191612e30565b820191906000526020600020905b815481529060010190602001808311612e1357829003601f168201915b5050925050506040516020818303038152906040528051906020012014905092915050565b60008060026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612ea0578082015181840152602081019050612e85565b50505050905090810190601f168015612ecd5780820380516001836020036101000a031916815260200191505b5092505050604051602081830303815290604052805190602001208152602001908152602001600020541415612f065760009050612f32565b6001612f1183612f37565b815481101515612f1d57fe5b90600052602060002090600302016002015490505b919050565b6000600160026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b83811015612f83578082015181840152602081019050612f68565b50505050905090810190601f168015612fb05780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061302357805160ff1916838001178555613051565b82800160010185558215613051579182015b82811115613050578251825591602001919060010190613035565b5b50905061305e9190613062565b5090565b61308491905b80821115613080576000816000905550600101613068565b5090565b9056fe656e6f646520696420646f6573206e6f742062656c6f6e6720746f2074686520706173736564206f7267696e76616c6964206f7065726174696f6e2e2077726f6e6720616374696f6e20706173736564656e6f646520696420646f6573206e6f742062656c6f6e6720746f2074686520706173736564206f7267206964a165627a7a7230582011179f2b111ff0fc199ae5bdfe206abf5283b1c344d947e24ad65df0e432745e0029 \ No newline at end of file diff --git a/permission/contract/gen/OrgManager.abi b/permission/contract/gen/OrgManager.abi new file mode 100644 index 0000000000..729c6ff9ed --- /dev/null +++ b/permission/contract/gen/OrgManager.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateOrg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"approveOrgStatusUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getUltimateParent","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pOrgId","type":"string"},{"name":"_orgId","type":"string"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"_getOrgIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgIndex","type":"uint256"}],"name":"getOrgInfo","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfOrgs","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"},{"name":"_orgStatus","type":"uint256"}],"name":"checkOrgStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_breadth","type":"uint256"},{"name":"_depth","type":"uint256"}],"name":"setUpOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approveOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"addOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"checkOrgExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"},{"indexed":false,"name":"_status","type":"uint256"}],"name":"OrgPendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_porgId","type":"string"},{"indexed":false,"name":"_ultParent","type":"string"},{"indexed":false,"name":"_level","type":"uint256"}],"name":"OrgSuspensionRevoked","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/OrgManager.bin b/permission/contract/gen/OrgManager.bin new file mode 100644 index 0000000000..0aa567e937 --- /dev/null +++ b/permission/contract/gen/OrgManager.bin @@ -0,0 +1 @@ +60806040526000600160146101000a81548160ff02191690831515021790555060046002556004600355600060065534801561003a57600080fd5b506040516020806140b48339810180604052602081101561005a57600080fd5b810190808051906020019092919050505080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613ff8806100bc6000396000f3fe608060405234801561001057600080fd5b50600436106100d1576000357c0100000000000000000000000000000000000000000000000000000000900480637755ebdd1161008e5780637755ebdd1461060c5780638c8642df1461062a5780639e58eb9f14610707578063e302831614610794578063f9953de51461080d578063ffe40d1d14610886576100d1565b80630cc27493146100d657806314f775f91461016d578063177c8d8a146101f05780631f953480146102e2578063320d2c39146103b05780635c4f32ee1461047f575b600080fd5b610157600480360360408110156100ec57600080fd5b810190808035906020019064010000000081111561010957600080fd5b82018360208201111561011b57600080fd5b8035906020019184600183028401116401000000008311171561013d57600080fd5b909192939192939080359060200190929190505050610959565b6040518082815260200191505060405180910390f35b6101ee6004803603604081101561018357600080fd5b81019080803590602001906401000000008111156101a057600080fd5b8201836020820111156101b257600080fd5b803590602001918460018302840111640100000000831117156101d457600080fd5b909192939192939080359060200190929190505050610e46565b005b6102676004803603602081101561020657600080fd5b810190808035906020019064010000000081111561022357600080fd5b82018360208201111561023557600080fd5b8035906020019184600183028401116401000000008311171561025757600080fd5b909192939192939050505061111f565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102a757808201518184015260208101905061028c565b50505050905090810190601f1680156102d45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ae600480360360408110156102f857600080fd5b810190808035906020019064010000000081111561031557600080fd5b82018360208201111561032757600080fd5b8035906020019184600183028401116401000000008311171561034957600080fd5b90919293919293908035906020019064010000000081111561036a57600080fd5b82018360208201111561037c57600080fd5b8035906020019184600183028401116401000000008311171561039e57600080fd5b909192939192939050505061138f565b005b610469600480360360208110156103c657600080fd5b81019080803590602001906401000000008111156103e357600080fd5b8201836020820111156103f557600080fd5b8035906020019184600183028401116401000000008311171561041757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611672565b6040518082815260200191505060405180910390f35b6104ab6004803603602081101561049557600080fd5b8101908080359060200190929190505050611705565b60405180806020018060200180602001868152602001858152602001848103845289818151815260200191508051906020019080838360005b838110156104ff5780820151818401526020810190506104e4565b50505050905090810190601f16801561052c5780820380516001836020036101000a031916815260200191505b50848103835288818151815260200191508051906020019080838360005b8381101561056557808201518184015260208101905061054a565b50505050905090810190601f1680156105925780820380516001836020036101000a031916815260200191505b50848103825287818151815260200191508051906020019080838360005b838110156105cb5780820151818401526020810190506105b0565b50505050905090810190601f1680156105f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b610614611996565b6040518082815260200191505060405180910390f35b6106ed6004803603604081101561064057600080fd5b810190808035906020019064010000000081111561065d57600080fd5b82018360208201111561066f57600080fd5b8035906020019184600183028401116401000000008311171561069157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506119a3565b604051808215151515815260200191505060405180910390f35b6107926004803603606081101561071d57600080fd5b810190808035906020019064010000000081111561073a57600080fd5b82018360208201111561074c57600080fd5b8035906020019184600183028401116401000000008311171561076e57600080fd5b90919293919293908035906020019092919080359060200190929190505050611a70565b005b61080b600480360360208110156107aa57600080fd5b81019080803590602001906401000000008111156107c757600080fd5b8201836020820111156107d957600080fd5b803590602001918460018302840111640100000000831117156107fb57600080fd5b9091929391929390505050611c47565b005b6108846004803603602081101561082357600080fd5b810190808035906020019064010000000081111561084057600080fd5b82018360208201111561085257600080fd5b8035906020019184600183028401116401000000008311171561087457600080fd5b9091929391929390505050612149565b005b61093f6004803603602081101561089c57600080fd5b81019080803590602001906401000000008111156108b957600080fd5b8201836020820111156108cb57600080fd5b803590602001918460018302840111640100000000831117156108ed57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506123d9565b604051808215151515815260200191505060405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d6020811015610a0957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515610b0e826123d9565b1515141515610b85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b6001831480610b945750600283145b1515610beb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180613f266025913960400191505060405180910390fd5b6000610c3a86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b90506001600482815481101515610c4d57fe5b906000526020600020906008020160060154141515610cb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180613f4b6027913960400191505060405180910390fd5b6000806001861415610cd0576002915060029050610ce3565b6002861415610ce25760049150600390505b5b60011515610d3589898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846119a3565b1515141515610d8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180613f726027913960400191505060405180910390fd5b6001861415610dea57610de588888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061246c565b610e38565b610e3788888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612767565b5b809450505050509392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610eca57600080fd5b505afa158015610ede573d6000803e3d6000fd5b505050506040513d6020811015610ef457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515610ff9826123d9565b1515141515611070576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b60018214156110cb576110c684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612a7f565b611119565b61111884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d8d565b5b50505050565b6060600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611282576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60046112d184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b8154811015156112dd57fe5b90600052602060002090600802016004018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113825780601f1061135757610100808354040283529160200191611382565b820191906000526020600020905b81548152906001019060200180831161136557829003601f168201915b5050505050905092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561141357600080fd5b505afa158015611427573d6000803e3d6000fd5b505050506040513d602081101561143d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156114f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b838383836040516020018085858082843780830192505050807f2e00000000000000000000000000000000000000000000000000000000000000815250600101838380828437808301925050509450505050506040516020818303038152906040526000151561155f826123d9565b15151415156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f7267206578697374730000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61166b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060028061309c565b5050505050565b6000600160056000846040516020018082805190602001908083835b6020831015156116b3578051825260208201915060208101905060208303925061168e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b606080606060008060048681548110151561171c57fe5b906000526020600020906008020160000160048781548110151561173c57fe5b906000526020600020906008020160020160048881548110151561175c57fe5b906000526020600020906008020160040160048981548110151561177c57fe5b90600052602060002090600802016006015460048a81548110151561179d57fe5b906000526020600020906008020160010154848054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118445780601f1061181957610100808354040283529160200191611844565b820191906000526020600020905b81548152906001019060200180831161182757829003601f168201915b50505050509450838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118e05780601f106118b5576101008083540402835291602001916118e0565b820191906000526020600020905b8154815290600101906020018083116118c357829003601f168201915b50505050509350828054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561197c5780601f106119515761010080835404028352916020019161197c565b820191906000526020600020905b81548152906001019060200180831161195f57829003601f168201915b505050505092509450945094509450945091939590929450565b6000600480549050905090565b6000806119af84611672565b9050600060056000866040516020018082805190602001908083835b6020831015156119f057805182526020820191506020810190506020830392506119cb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081526020019081526020016000205414158015611a67575082600482815481101515611a5357fe5b906000526020600020906008020160010154145b91505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611af457600080fd5b505afa158015611b08573d6000803e3d6000fd5b505050506040513d6020811015611b1e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611c33602060405190810160405280600081525085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001600261309c565b806002819055508160038190555050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611ccb57600080fd5b505afa158015611cdf573d6000803e3d6000fd5b505050506040513d6020811015611cf557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60011515611dfb83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060016119a3565b1515141515611e72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000611ec183838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611672565b90506002600482815481101515611ed457fe5b9060005260206000209060080201600101819055507fd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c600482815481101515611f1957fe5b9060005260206000209060080201600001600483815481101515611f3957fe5b9060005260206000209060080201600201600484815481101515611f5957fe5b9060005260206000209060080201600401600485815481101515611f7957fe5b90600052602060002090600802016006015460026040518080602001806020018060200186815260200185815260200184810384528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561202a5780601f10611fff5761010080835404028352916020019161202a565b820191906000526020600020905b81548152906001019060200180831161200d57829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156120ad5780601f10612082576101008083540402835291602001916120ad565b820191906000526020600020905b81548152906001019060200180831161209057829003601f168201915b50508481038252878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156121305780601f1061210557610100808354040283529160200191612130565b820191906000526020600020905b81548152906001019060200180831161211357829003601f168201915b50509850505050505050505060405180910390a1505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156121cd57600080fd5b505afa1580156121e1573d6000803e3d6000fd5b505050506040513d60208110156121f757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b81818080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600015156122fc826123d9565b1515141515612373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f7267206578697374730000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6123d4602060405190810160405280600081525084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060018061309c565b505050565b60008060056000846040516020018082805190602001908083835b60208310151561241957805182526020820191506020810190506020830392506123f4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081526020019081526020016000205414159050919050565b6001151561247b8260026119a3565b15151415156124d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180613f996034913960400191505060405180910390fd5b60006124e082611672565b905060036004828154811015156124f357fe5b9060005260206000209060080201600101819055507f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561253857fe5b906000526020600020906008020160000160048381548110151561255857fe5b906000526020600020906008020160020160048481548110151561257857fe5b906000526020600020906008020160040160048581548110151561259857fe5b9060005260206000209060080201600601546003604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156126495780601f1061261e57610100808354040283529160200191612649565b820191906000526020600020905b81548152906001019060200180831161262c57829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156126cc5780601f106126a1576101008083540402835291602001916126cc565b820191906000526020600020905b8154815290600101906020018083116126af57829003601f168201915b505084810382528781815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561274f5780601f106127245761010080835404028352916020019161274f565b820191906000526020600020905b81548152906001019060200180831161273257829003601f168201915b50509850505050505050505060405180910390a15050565b600115156127768260046119a3565b15151415156127ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e2073757370656e64656420737461746500000000000081525060200191505060405180910390fd5b60006127f882611672565b9050600560048281548110151561280b57fe5b9060005260206000209060080201600101819055507f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561285057fe5b906000526020600020906008020160000160048381548110151561287057fe5b906000526020600020906008020160020160048481548110151561289057fe5b90600052602060002090600802016004016004858154811015156128b057fe5b9060005260206000209060080201600601546005604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156129615780601f1061293657610100808354040283529160200191612961565b820191906000526020600020905b81548152906001019060200180831161294457829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156129e45780601f106129b9576101008083540402835291602001916129e4565b820191906000526020600020905b8154815290600101906020018083116129c757829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612a675780601f10612a3c57610100808354040283529160200191612a67565b820191906000526020600020905b815481529060010190602001808311612a4a57829003601f168201915b50509850505050505050505060405180910390a15050565b60011515612a8e8260036119a3565b1515141515612b05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000612b1082611672565b905060048082815481101515612b2257fe5b9060005260206000209060080201600101819055507f73ccf8d6c8385bf5347269bd59712da33183c1a5e1702494bcdb87d0f4674d96600482815481101515612b6757fe5b9060005260206000209060080201600001600483815481101515612b8757fe5b9060005260206000209060080201600201600484815481101515612ba757fe5b9060005260206000209060080201600401600485815481101515612bc757fe5b90600052602060002090600802016006015460405180806020018060200180602001858152602001848103845288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612c705780601f10612c4557610100808354040283529160200191612c70565b820191906000526020600020905b815481529060010190602001808311612c5357829003601f168201915b5050848103835287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612cf35780601f10612cc857610100808354040283529160200191612cf3565b820191906000526020600020905b815481529060010190602001808311612cd657829003601f168201915b5050848103825286818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612d765780601f10612d4b57610100808354040283529160200191612d76565b820191906000526020600020905b815481529060010190602001808311612d5957829003601f168201915b505097505050505050505060405180910390a15050565b60011515612d9c8260056119a3565b1515141515612e13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000612e1e82611672565b90506002600482815481101515612e3157fe5b9060005260206000209060080201600101819055507f882f030c609566cd82918a97d457fd48f9cfcefd11282e2654cde3f94579c15f600482815481101515612e7657fe5b9060005260206000209060080201600001600483815481101515612e9657fe5b9060005260206000209060080201600201600484815481101515612eb657fe5b9060005260206000209060080201600401600485815481101515612ed657fe5b90600052602060002090600802016006015460405180806020018060200180602001858152602001848103845288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612f7f5780601f10612f5457610100808354040283529160200191612f7f565b820191906000526020600020905b815481529060010190602001808311612f6257829003601f168201915b50508481038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130025780601f10612fd757610100808354040283529160200191613002565b820191906000526020600020905b815481529060010190602001808311612fe557829003601f168201915b50508481038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130855780601f1061305a57610100808354040283529160200191613085565b820191906000526020600020905b81548152906001019060200180831161306857829003601f168201915b505097505050505050505060405180910390a15050565b600080905060008090506000809050600185141561312f57856040516020018082805190602001908083835b6020831015156130ed57805182526020820191506020810190506020830392506130c8565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001209150613299565b866040516020018082805190602001908083835b6020831015156131685780518252602082019150602081019050602083039250613143565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120925086866040516020018083805190602001908083835b6020831015156131df57805182526020820191506020810190506020830392506131ba565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e0000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b60208310151561325a5780518252602082019150602081019050602083039250613235565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040528051906020012091505b60066000815480929190600101919050555060065460056000848152602001908152602001600020819055506000600480548091906001016132db9190613cab565b905060018614156133a057856004828154811015156132f657fe5b906000526020600020906008020160060181905550600060048281548110151561331c57fe5b9060005260206000209060080201600501819055508660048281548110151561334157fe5b90600052602060002090600802016003019080519060200190613365929190613cdd565b508660048281548110151561337657fe5b9060005260206000209060080201600401908051906020019061339a929190613cdd565b5061374d565b600160056000868152602001908152602001600020540391506003546004838154811015156133cb57fe5b906000526020600020906008020160070180549050101515613455576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f62726561647468206c6576656c2065786365656465640000000000000000000081525060200191505060405180910390fd5b60025460048381548110151561346757fe5b9060005260206000209060080201600601541015156134ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f6465707468206c6576656c20657863656564656400000000000000000000000081525060200191505060405180910390fd5b60016004838154811015156134ff57fe5b9060005260206000209060080201600601540160048281548110151561352157fe5b9060005260206000209060080201600601819055508160048281548110151561354657fe5b90600052602060002090600802016005018190555060048281548110151561356a57fe5b906000526020600020906008020160040160048281548110151561358a57fe5b906000526020600020906008020160040190805460018160011615610100020316600290046135ba929190613d5d565b5060006004838154811015156135cc57fe5b906000526020600020906008020160070180548091906001016135ef9190613de4565b90508160048481548110151561360157fe5b90600052602060002090600802016007018281548110151561361f57fe5b906000526020600020018190555088886040516020018083805190602001908083835b6020831015156136675780518252602082019150602081019050602083039250613642565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e0000000000000000000000000000000000000000000000000000000000000081525060010182805190602001908083835b6020831015156136e257805182526020820191506020810190506020830392506136bd565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405260048381548110151561372657fe5b9060005260206000209060080201600301908051906020019061374a929190613cdd565b50505b8660048281548110151561375d57fe5b90600052602060002090600802016000019080519060200190613781929190613cdd565b508760048281548110151561379257fe5b906000526020600020906008020160020190805190602001906137b6929190613cdd565b50846004828154811015156137c757fe5b9060005260206000209060080201600101819055506001851415613a45577f0e8b7be64e0c730234ba2cd252b227fb481d7a247ba806d1941144c535bf054b60048281548110151561381557fe5b906000526020600020906008020160000160048381548110151561383557fe5b906000526020600020906008020160020160048481548110151561385557fe5b906000526020600020906008020160040160048581548110151561387557fe5b9060005260206000209060080201600601546001604051808060200180602001806020018681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139265780601f106138fb57610100808354040283529160200191613926565b820191906000526020600020905b81548152906001019060200180831161390957829003601f168201915b50508481038352888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156139a95780601f1061397e576101008083540402835291602001916139a9565b820191906000526020600020905b81548152906001019060200180831161398c57829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613a2c5780601f10613a0157610100808354040283529160200191613a2c565b820191906000526020600020905b815481529060010190602001808311613a0f57829003601f168201915b50509850505050505050505060405180910390a1613ca1565b7fd705723a50859c9cc1d3953e10b8b9478820e7a62927ad3215897ed87b20591c600482815481101515613a7557fe5b9060005260206000209060080201600001600483815481101515613a9557fe5b9060005260206000209060080201600201600484815481101515613ab557fe5b9060005260206000209060080201600401600485815481101515613ad557fe5b906000526020600020906008020160060154600260405180806020018060200180602001868152602001858152602001848103845289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613b865780601f10613b5b57610100808354040283529160200191613b86565b820191906000526020600020905b815481529060010190602001808311613b6957829003601f168201915b5050848103835288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613c095780601f10613bde57610100808354040283529160200191613c09565b820191906000526020600020905b815481529060010190602001808311613bec57829003601f168201915b5050848103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613c8c5780601f10613c6157610100808354040283529160200191613c8c565b820191906000526020600020905b815481529060010190602001808311613c6f57829003601f168201915b50509850505050505050505060405180910390a15b5050505050505050565b815481835581811115613cd857600802816008028360005260206000209182019101613cd79190613e10565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d1e57805160ff1916838001178555613d4c565b82800160010185558215613d4c579182015b82811115613d4b578251825591602001919060010190613d30565b5b509050613d599190613e97565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d965780548555613dd3565b82800160010185558215613dd357600052602060002091601f016020900482015b82811115613dd2578254825591600101919060010190613db7565b5b509050613de09190613e97565b5090565b815481835581811115613e0b57818360005260206000209182019101613e0a9190613e97565b5b505050565b613e9491905b80821115613e905760008082016000613e2f9190613ebc565b6001820160009055600282016000613e479190613ebc565b600382016000613e579190613ebc565b600482016000613e679190613ebc565b60058201600090556006820160009055600782016000613e879190613f04565b50600801613e16565b5090565b90565b613eb991905b80821115613eb5576000816000905550600101613e9d565b5090565b90565b50805460018160011615610100020316600290046000825580601f10613ee25750613f01565b601f016020900490600052602060002090810190613f009190613e97565b5b50565b5080546000825590600052602060002090810190613f229190613e97565b5056fe696e76616c696420616374696f6e2e206f7065726174696f6e206e6f7420616c6c6f7765646e6f742061206d6173746572206f72672e206f7065726174696f6e206e6f7420616c6c6f7765646f72672073746174757320646f6573206e6f7420616c6c6f7720746865206f7065726174696f6e6f7267206e6f7420696e20617070726f766564207374617475732e206f7065726174696f6e2063616e6e6f7420626520646f6e65a165627a7a72305820ad4f7ede501fde744bd99a211aae38fa1573644d4dc550d1c4e668f404270efd0029 \ No newline at end of file diff --git a/permission/contract/gen/PermissionsImplementation.abi b/permission/contract/gen/PermissionsImplementation.abi new file mode 100644 index 0000000000..03cffdab7e --- /dev/null +++ b/permission/contract/gen/PermissionsImplementation.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_action","type":"uint256"},{"name":"_caller","type":"address"}],"name":"updateAccountStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_access","type":"uint256"},{"name":"_voter","type":"bool"},{"name":"_admin","type":"bool"},{"name":"_caller","type":"address"}],"name":"addNewRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nwAdminOrg","type":"string"},{"name":"_nwAdminRole","type":"string"},{"name":"_oAdminRole","type":"string"}],"name":"setPolicy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_caller","type":"address"}],"name":"startBlacklistedAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_account","type":"address"},{"name":"_caller","type":"address"}],"name":"approveOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"},{"name":"_caller","type":"address"}],"name":"updateOrgStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"}],"name":"addAdminNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_roleId","type":"string"},{"name":"_caller","type":"address"}],"name":"assignAdminRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"updateNetworkBootStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_caller","type":"address"}],"name":"approveBlacklistedAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNetworkBootStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"addAdminAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_caller","type":"address"}],"name":"addNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_caller","type":"address"}],"name":"removeRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_caller","type":"address"}],"name":"approveBlacklistedNodeRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"}],"name":"validateAccount","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_caller","type":"address"}],"name":"approveAdminRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"},{"name":"_roleId","type":"string"},{"name":"_caller","type":"address"}],"name":"assignAccountRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"}],"name":"isOrgAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_breadth","type":"uint256"},{"name":"_depth","type":"uint256"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_pOrgId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_caller","type":"address"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"},{"name":"_caller","type":"address"}],"name":"approveOrgStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_caller","type":"address"}],"name":"startBlacklistedNodeRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPolicyDetails","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"isNetworkAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_action","type":"uint256"},{"name":"_caller","type":"address"}],"name":"updateNodeStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getPendingOp","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nwAdminOrg","type":"string"},{"name":"_nwAdminRole","type":"string"},{"name":"_oAdminRole","type":"string"},{"name":"_networkBootStatus","type":"bool"}],"name":"setMigrationPolicy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_account","type":"address"},{"name":"_caller","type":"address"}],"name":"addOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"},{"name":"_orgManager","type":"address"},{"name":"_rolesManager","type":"address"},{"name":"_accountManager","type":"address"},{"name":"_voterManager","type":"address"},{"name":"_nodeManager","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_networkBootStatus","type":"bool"}],"name":"PermissionsInitialized","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/PermissionsImplementation.bin b/permission/contract/gen/PermissionsImplementation.bin new file mode 100644 index 0000000000..f9b506954b --- /dev/null +++ b/permission/contract/gen/PermissionsImplementation.bin @@ -0,0 +1 @@ +608060405260036009556000600a60006101000a81548160ff0219169083151502179055503480156200003157600080fd5b5060405160c0806200a14c833981018060405260c08110156200005357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505085600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505050619f1b80620002316000396000f3fe608060405234801561001057600080fd5b50600436106101ec576000357c010000000000000000000000000000000000000000000000000000000090048063655a8ef511610121578063b5546564116100bf578063dbfad7111161008e578063dbfad711146115e2578063f346a3a7146116da578063f5ad584a14611872578063f922f802146119a1576101ec565b8063b55465641461128f578063c3dc8e0914611332578063cc9ba6fa14611420578063d1aa0c2014611586576101ec565b80638baa8191116100fb5780638baa819114610e8f5780639bd3810114611021578063a5843f0814611114578063a64d28601461114c576101ec565b8063655a8ef514610bf55780636b568d7614610ce35780638884304114610dd6576101ec565b8063404bf3eb1161018e5780634cbfa82e116101685780634cbfa82e146109b35780634fe57e7a146109d557806359a260a314610a195780635ca5adbe14610b07576101ec565b8063404bf3eb146107ca57806344478e79146108d85780634b20f45f146108fa576101ec565b80631c249912116101ca5780631c249912146104e75780633bc07dea146105a05780633cf5f33b146106ae5780633f25c28814610751576101ec565b806304e81f1e146101f15780631b04c276146102b45780631b610220146103c4575b600080fd5b6102b26004803603608081101561020757600080fd5b810190808035906020019064010000000081111561022457600080fd5b82018360208201111561023657600080fd5b8035906020019184600183028401116401000000008311171561025857600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611aaf565b005b6103c2600480360360c08110156102ca57600080fd5b81019080803590602001906401000000008111156102e757600080fd5b8201836020820111156102f957600080fd5b8035906020019184600183028401116401000000008311171561031b57600080fd5b90919293919293908035906020019064010000000081111561033c57600080fd5b82018360208201111561034e57600080fd5b8035906020019184600183028401116401000000008311171561037057600080fd5b909192939192939080359060200190929190803515159060200190929190803515159060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e2b565b005b6104e5600480360360608110156103da57600080fd5b81019080803590602001906401000000008111156103f757600080fd5b82018360208201111561040957600080fd5b8035906020019184600183028401116401000000008311171561042b57600080fd5b90919293919293908035906020019064010000000081111561044c57600080fd5b82018360208201111561045e57600080fd5b8035906020019184600183028401116401000000008311171561048057600080fd5b9091929391929390803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b909192939192939050505061221c565b005b61059e600480360360608110156104fd57600080fd5b810190808035906020019064010000000081111561051a57600080fd5b82018360208201111561052c57600080fd5b8035906020019184600183028401116401000000008311171561054e57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061242b565b005b6106ac600480360360808110156105b657600080fd5b81019080803590602001906401000000008111156105d357600080fd5b8201836020820111156105e557600080fd5b8035906020019184600183028401116401000000008311171561060757600080fd5b90919293919293908035906020019064010000000081111561062857600080fd5b82018360208201111561063a57600080fd5b8035906020019184600183028401116401000000008311171561065c57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128a0565b005b61074f600480360360608110156106c457600080fd5b81019080803590602001906401000000008111156106e157600080fd5b8201836020820111156106f357600080fd5b8035906020019184600183028401116401000000008311171561071557600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613058565b005b6107c86004803603602081101561076757600080fd5b810190808035906020019064010000000081111561078457600080fd5b82018360208201111561079657600080fd5b803590602001918460018302840111640100000000831117156107b857600080fd5b90919293919293905050506134c1565b005b6108d6600480360360808110156107e057600080fd5b81019080803590602001906401000000008111156107fd57600080fd5b82018360208201111561080f57600080fd5b8035906020019184600183028401116401000000008311171561083157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561087257600080fd5b82018360208201111561088457600080fd5b803590602001918460018302840111640100000000831117156108a657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506137f6565b005b6108e0613d6b565b604051808215151515815260200191505060405180910390f35b6109b16004803603606081101561091057600080fd5b810190808035906020019064010000000081111561092d57600080fd5b82018360208201111561093f57600080fd5b8035906020019184600183028401116401000000008311171561096157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6e565b005b6109bb6142de565b604051808215151515815260200191505060405180910390f35b610a17600480360360208110156109eb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142f5565b005b610b0560048036036060811015610a2f57600080fd5b8101908080359060200190640100000000811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b80359060200191846001830284011164010000000083111715610a8057600080fd5b909192939192939080359060200190640100000000811115610aa157600080fd5b820183602082011115610ab357600080fd5b80359060200191846001830284011164010000000083111715610ad557600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614762565b005b610bf360048036036060811015610b1d57600080fd5b8101908080359060200190640100000000811115610b3a57600080fd5b820183602082011115610b4c57600080fd5b80359060200191846001830284011164010000000083111715610b6e57600080fd5b909192939192939080359060200190640100000000811115610b8f57600080fd5b820183602082011115610ba157600080fd5b80359060200191846001830284011164010000000083111715610bc357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614b30565b005b610ce160048036036060811015610c0b57600080fd5b8101908080359060200190640100000000811115610c2857600080fd5b820183602082011115610c3a57600080fd5b80359060200191846001830284011164010000000083111715610c5c57600080fd5b909192939192939080359060200190640100000000811115610c7d57600080fd5b820183602082011115610c8f57600080fd5b80359060200191846001830284011164010000000083111715610cb157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615178565b005b610dbc60048036036040811015610cf957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610d3657600080fd5b820183602082011115610d4857600080fd5b80359060200191846001830284011164010000000083111715610d6a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506154ea565b604051808215151515815260200191505060405180910390f35b610e8d60048036036060811015610dec57600080fd5b8101908080359060200190640100000000811115610e0957600080fd5b820183602082011115610e1b57600080fd5b80359060200191846001830284011164010000000083111715610e3d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615656565b005b61101f60048036036080811015610ea557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ee257600080fd5b820183602082011115610ef457600080fd5b80359060200191846001830284011164010000000083111715610f1657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610f7957600080fd5b820183602082011115610f8b57600080fd5b80359060200191846001830284011164010000000083111715610fad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615c48565b005b6110fa6004803603604081101561103757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561107457600080fd5b82018360208201111561108657600080fd5b803590602001918460018302840111640100000000831117156110a857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061635e565b604051808215151515815260200191505060405180910390f35b61114a6004803603604081101561112a57600080fd5b8101908080359060200190929190803590602001909291905050506168a9565b005b61128d6004803603608081101561116257600080fd5b810190808035906020019064010000000081111561117f57600080fd5b82018360208201111561119157600080fd5b803590602001918460018302840111640100000000831117156111b357600080fd5b9091929391929390803590602001906401000000008111156111d457600080fd5b8201836020820111156111e657600080fd5b8035906020019184600183028401116401000000008311171561120857600080fd5b90919293919293908035906020019064010000000081111561122957600080fd5b82018360208201111561123b57600080fd5b8035906020019184600183028401116401000000008311171561125d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616f4a565b005b611330600480360360608110156112a557600080fd5b81019080803590602001906401000000008111156112c257600080fd5b8201836020820111156112d457600080fd5b803590602001918460018302840111640100000000831117156112f657600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050617527565b005b61141e6004803603606081101561134857600080fd5b810190808035906020019064010000000081111561136557600080fd5b82018360208201111561137757600080fd5b8035906020019184600183028401116401000000008311171561139957600080fd5b9091929391929390803590602001906401000000008111156113ba57600080fd5b8201836020820111156113cc57600080fd5b803590602001918460018302840111640100000000831117156113ee57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506179dc565b005b611428617e74565b6040518080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b8381101561147a57808201518184015260208101905061145f565b50505050905090810190601f1680156114a75780820380516001836020036101000a031916815260200191505b50848103835287818151815260200191508051906020019080838360005b838110156114e05780820151818401526020810190506114c5565b50505050905090810190601f16801561150d5780820380516001836020036101000a031916815260200191505b50848103825286818151815260200191508051906020019080838360005b8381101561154657808201518184015260208101905061152b565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b6115c86004803603602081101561159c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050618073565b604051808215151515815260200191505060405180910390f35b6116d8600480360360808110156115f857600080fd5b810190808035906020019064010000000081111561161557600080fd5b82018360208201111561162757600080fd5b8035906020019184600183028401116401000000008311171561164957600080fd5b90919293919293908035906020019064010000000081111561166a57600080fd5b82018360208201111561167c57600080fd5b8035906020019184600183028401116401000000008311171561169e57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506182fd565b005b611751600480360360208110156116f057600080fd5b810190808035906020019064010000000081111561170d57600080fd5b82018360208201111561171f57600080fd5b8035906020019184600183028401116401000000008311171561174157600080fd5b909192939192939050505061867b565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156117cd5780820151818401526020810190506117b2565b50505050905090810190601f1680156117fa5780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b83811015611833578082015181840152602081019050611818565b50505050905090810190601f1680156118605780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b61199f6004803603608081101561188857600080fd5b81019080803590602001906401000000008111156118a557600080fd5b8201836020820111156118b757600080fd5b803590602001918460018302840111640100000000831117156118d957600080fd5b9091929391929390803590602001906401000000008111156118fa57600080fd5b82018360208201111561190c57600080fd5b8035906020019184600183028401116401000000008311171561192e57600080fd5b90919293919293908035906020019064010000000081111561194f57600080fd5b82018360208201111561196157600080fd5b8035906020019184600183028401116401000000008311171561198357600080fd5b9091929391929390803515159060200190929190505050618844565b005b611aad600480360360808110156119b757600080fd5b81019080803590602001906401000000008111156119d457600080fd5b8201836020820111156119e657600080fd5b80359060200191846001830284011164010000000083111715611a0857600080fd5b909192939192939080359060200190640100000000811115611a2957600080fd5b820183602082011115611a3b57600080fd5b80359060200191846001830284011164010000000083111715611a5d57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506189ef565b005b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611b3357600080fd5b505afa158015611b47573d6000803e3d6000fd5b505050506040513d6020811015611b5d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515611c47838361635e565b1515141515611ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b6001841480611cb05750600284145b80611cbb5750600384145b1515611d12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180619e5b6025913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a888888886040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611e0a57600080fd5b505af1158015611e1e573d6000803e3d6000fd5b5050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611eaf57600080fd5b505afa158015611ec3573d6000803e3d6000fd5b505050506040513d6020811015611ed957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515611fc182619245565b1515141515612038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001151561208c838361635e565b15151415156120e6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b7135798c8c8c8c8c8c8c6040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001868152602001851515151581526020018415151515815260200183810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508381038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509950505050505050505050600060405180830381600087803b1580156121f757600080fd5b505af115801561220b573d6000803e3d6000fd5b505050505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156122a057600080fd5b505afa1580156122b4573d6000803e3d6000fd5b505050506040513d60208110156122ca57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612360576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff1615151415156123ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8686600691906123fd929190619db5565b5084846007919061240f929190619db5565b50828260089190612421929190619db5565b5050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156124af57600080fd5b505afa1580156124c3573d6000803e3d6000fd5b505050506040513d60208110156124d957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561256f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b806001151561257d82618073565b15151415156125d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a86868660046040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156126d057600080fd5b505af11580156126e4573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600687878760066040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156128215780601f106127f657610100808354040283529160200191612821565b820191906000526020600020905b81548152906001019060200180831161280457829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b15801561288157600080fd5b505af1158015612895573d6000803e3d6000fd5b505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561292457600080fd5b505afa158015612938573d6000803e3d6000fd5b505050506040513d602081101561294e57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156129e4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156129f282618073565b1515141515612a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b60011515612a9f88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001619386565b1515141515612b16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b612bbc60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612baf5780601f10612b8457610100808354040283529160200191612baf565b820191906000526020600020905b815481529060010190602001808311612b9257829003601f168201915b50505050508360016194c7565b1561304f57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e302831688886040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015612c7e57600080fd5b505af1158015612c92573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b713579600889896009546001806040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018681526020018515151515815260200184151515158152602001838103835289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612db05780601f10612d8557610100808354040283529160200191612db0565b820191906000526020600020905b815481529060010190602001808311612d9357829003601f168201915b50508381038252888882818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612e0157600080fd5b505af1158015612e15573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386bc365286868a8a6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c214e5e58888866040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b15801561301257600080fd5b505af1158015613026573d6000803e3d6000fd5b505050506040513d602081101561303c57600080fd5b8101908080519060200190929190505050505b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156130dc57600080fd5b505afa1580156130f0573d6000803e3d6000fd5b505050506040513d602081101561310657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561319c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156131aa82618073565b1515141515613204576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc274938787876040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b1580156132cb57600080fd5b505af11580156132df573d6000803e3d6000fd5b505050506040513d60208110156132f557600080fd5b81019080805190602001909291905050509050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600688886000866040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156134415780601f1061341657610100808354040283529160200191613441565b820191906000526020600020905b81548152906001019060200180831161342457829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b1580156134a157600080fd5b505af11580156134b5573d6000803e3d6000fd5b50505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561354557600080fd5b505afa158015613559573d6000803e3d6000fd5b505050506040513d602081101561356f57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613605576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515613691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3b09d84848460066040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352868682818152602001925080828437600081840152601f19601f8201169050808301925050508381038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156137b65780601f1061378b576101008083540402835291602001916137b6565b820191906000526020600020905b81548152906001019060200180831161379957829003601f168201915b505095505050505050600060405180830381600087803b1580156137d957600080fd5b505af11580156137ed573d6000803e3d6000fd5b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561387a57600080fd5b505afa15801561388e573d6000803e3d6000fd5b505050506040513d60208110156138a457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561393a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001151561398c8261963f565b1515141515613a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b8160011515613a1182618073565b1515141515613a6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d878a8a898960016040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015613b9857600080fd5b505af1158015613bac573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d60068a8a8a60046040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848103845289818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015613ce95780601f10613cbe57610100808354040283529160200191613ce9565b820191906000526020600020905b815481529060010190602001808311613ccc57829003601f168201915b50508481038352888882818152602001925080828437600081840152601f19601f82011690508083019250505084810382526000815260200160200198505050505050505050600060405180830381600087803b158015613d4957600080fd5b505af1158015613d5d573d6000803e3d6000fd5b505050505050505050505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613df157600080fd5b505afa158015613e05573d6000803e3d6000fd5b505050506040513d6020811015613e1b57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613eb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515613f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b6001600a60006101000a81548160ff021916908315150217905550600a60009054906101000a900460ff1691505090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015613ff257600080fd5b505afa158015614006573d6000803e3d6000fd5b505050506040513d602081101561401c57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156140b2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156140c082618073565b151514151561411a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6141c060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156141b35780601f10614188576101008083540402835291602001916141b3565b820191906000526020600020905b81548152906001019060200180831161419657829003601f168201915b50505050508360066194c7565b156142d7576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166384b7a84a86868660056040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156142be57600080fd5b505af11580156142d2573d6000803e3d6000fd5b505050505b5050505050565b6000600a60009054906101000a900460ff16905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561437957600080fd5b505afa15801561438d573d6000803e3d6000fd5b505050506040513d60208110156143a357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515614439576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff1615151415156144c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b61456b60068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561455e5780601f106145335761010080835404028352916020019161455e565b820191906000526020600020905b81548152906001019060200180831161454157829003601f168201915b5050505050836001619777565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d836006600760026040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184815260200183810383528681815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561469f5780601f106146745761010080835404028352916020019161469f565b820191906000526020600020905b81548152906001019060200180831161468257829003601f168201915b50508381038252858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156147225780601f106146f757610100808354040283529160200191614722565b820191906000526020600020905b81548152906001019060200180831161470557829003601f168201915b50509650505050505050600060405180830381600087803b15801561474657600080fd5b505af115801561475a573d6000803e3d6000fd5b505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156147e657600080fd5b505afa1580156147fa573d6000803e3d6000fd5b505050506040513d602081101561481057600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156148a6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156148f882619245565b151514151561496f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156149c3838361635e565b1515141515614a1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f5e1a4587878b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015614b0e57600080fd5b505af1158015614b22573d6000803e3d6000fd5b505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015614bb457600080fd5b505afa158015614bc8573d6000803e3d6000fd5b505050506040513d6020811015614bde57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515614c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515614cc682619245565b1515141515614d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515614d91838361635e565b1515141515614deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b60076040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015614e795780601f10614e4e57610100808354040283529160200191614e79565b820191906000526020600020905b815481529060010190602001808311614e5c57829003601f168201915b50509250505060405160208183030381529060405280519060200120888860405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014158015614ff1575060086040516020018080602001828103825283818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015614f7f5780601f10614f5457610100808354040283529160200191614f7f565b820191906000526020600020905b815481529060010190602001808311614f6257829003601f168201915b50509250505060405160208183030381529060405280519060200120888860405160200180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040516020818303038152906040528051906020012014155b1515615065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f61646d696e20726f6c65732063616e6e6f742062652072656d6f76656400000081525060200191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a6343012898989896040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b15801561515657600080fd5b505af115801561516a573d6000803e3d6000fd5b505050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156151fc57600080fd5b505afa158015615210573d6000803e3d6000fd5b505050506040513d602081101561522657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156152bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156152ca82618073565b1515141515615324576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6153ca60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156153bd5780601f10615392576101008083540402835291602001916153bd565b820191906000526020600020905b8154815290600101906020018083116153a057829003601f168201915b50505050508360056194c7565b156154e257600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc501468585898960056040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156154c957600080fd5b505af11580156154dd573d6000803e3d6000fd5b505050505b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b568d7684846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156155c85780820151818401526020810190506155ad565b50505050905090810190601f1680156155f55780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561561357600080fd5b505afa158015615627573d6000803e3d6000fd5b505050506040513d602081101561563d57600080fd5b8101908080519060200190929190505050905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156156da57600080fd5b505afa1580156156ee573d6000803e3d6000fd5b505050506040513d602081101561570457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561579a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b80600115156157a882618073565b1515141515615802576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b6158a860068054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561589b5780601f106158705761010080835404028352916020019161589b565b820191906000526020600020905b81548152906001019060200180831161587e57829003601f168201915b50505050508360046194c7565b15615c41576000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631d09dc9388886040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505093505050506040805180830381600087803b15801561596b57600080fd5b505af115801561597f573d6000803e3d6000fd5b505050506040513d604081101561599557600080fd5b810190808051906020019092919080519060200190929190505050915091508115615a6157615a6060068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015615a535780601f10615a2857610100808354040283529160200191615a53565b820191906000526020600020905b815481529060010190602001808311615a3657829003601f168201915b5050505050826000619777565b5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c214e5e58989896040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050602060405180830381600087803b158015615b5357600080fd5b505af1158015615b67573d6000803e3d6000fd5b505050506040513d6020811015615b7d57600080fd5b810190808051906020019092919050505090508015615c3d57615c3c60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015615c2f5780601f10615c0457610100808354040283529160200191615c2f565b820191906000526020600020905b815481529060010190602001808311615c1257829003601f168201915b5050505050876001619777565b5b5050505b5050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015615ccc57600080fd5b505afa158015615ce0573d6000803e3d6000fd5b505050506040513d6020811015615cf657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515615d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b808360011515615d9c838361635e565b1515141515615df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b8460011515615e0482619245565b1515141515615e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6f7267206e6f7420696e20617070726f7665642073746174757300000000000081525060200191505060405180910390fd5b60011515615e8988886154ea565b1515141515615f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b60011515615f0e8688619a0c565b1515141515615f85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f726f6c6520646f6573206e6f742065786973747300000000000000000000000081525060200191505060405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663be322e548789615fd08b619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015616043578082015181840152602081019050616028565b50505050905090810190601f1680156160705780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156160a957808201518184015260208101905061608e565b50505050905090810190601f1680156160d65780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b8381101561610f5780820151818401526020810190506160f4565b50505050905090810190601f16801561613c5780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b15801561615d57600080fd5b505afa158015616171573d6000803e3d6000fd5b505050506040513d602081101561618757600080fd5b810190808051906020019092919050505090506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663143a5604898989856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184151515158152602001838103835286818151815260200191508051906020019080838360005b8381101561628657808201518184015260208101905061626b565b50505050905090810190601f1680156162b35780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156162ec5780820151818401526020810190506162d1565b50505050905090810190601f1680156163195780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561633c57600080fd5b505af1158015616350573d6000803e3d6000fd5b505050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8b42bf484846163a886619c27565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561644957808201518184015260208101905061642e565b50505050905090810190601f1680156164765780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156164af578082015181840152602081019050616494565b50505050905090810190601f1680156164dc5780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038186803b1580156164fc57600080fd5b505afa158015616510573d6000803e3d6000fd5b505050506040513d602081101561652657600080fd5b81019080805190602001909291905050501561654557600190506168a3565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663be322e546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381d66b23866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060006040518083038186803b15801561663d57600080fd5b505afa158015616651573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561667b57600080fd5b81019080805164010000000081111561669357600080fd5b828101905060208101848111156166a957600080fd5b81518560018202830111640100000000821117156166c657600080fd5b5050929190505050846166d886619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b8381101561674b578082015181840152602081019050616730565b50505050905090810190601f1680156167785780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156167b1578082015181840152602081019050616796565b50505050905090810190601f1680156167de5780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156168175780820151818401526020810190506167fc565b50505050905090810190601f1680156168445780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b15801561686557600080fd5b505afa158015616879573d6000803e3d6000fd5b505050506040513d602081101561688f57600080fd5b810190808051906020019092919050505090505b92915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561692d57600080fd5b505afa158015616941573d6000803e3d6000fd5b505050506040513d602081101561695757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156169ed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515616a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639e58eb9f600685856040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001848152602001838152602001828103825285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616b7b5780601f10616b5057610100808354040283529160200191616b7b565b820191906000526020600020905b815481529060010190602001808311616b5e57829003601f168201915b5050945050505050600060405180830381600087803b158015616b9d57600080fd5b505af1158015616bb1573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b713579600760066009546001806040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018681526020018515151515815260200184151515158152602001838103835288818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616ccf5780601f10616ca457610100808354040283529160200191616ccf565b820191906000526020600020905b815481529060010190602001808311616cb257829003601f168201915b5050838103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616d525780601f10616d2757610100808354040283529160200191616d52565b820191906000526020600020905b815481529060010190602001808311616d3557829003601f168201915b5050975050505050505050600060405180830381600087803b158015616d7757600080fd5b505af1158015616d8b573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cef7f6af600760086040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616e885780601f10616e5d57610100808354040283529160200191616e88565b820191906000526020600020905b815481529060010190602001808311616e6b57829003601f168201915b5050838103825284818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015616f0b5780601f10616ee057610100808354040283529160200191616f0b565b820191906000526020600020905b815481529060010190602001808311616eee57829003601f168201915b5050945050505050600060405180830381600087803b158015616f2d57600080fd5b505af1158015616f41573d6000803e3d6000fd5b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015616fce57600080fd5b505afa158015616fe2573d6000803e3d6000fd5b505050506040513d6020811015616ff857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561708e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156170e08261963f565b1515141515617157576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f726720646f6573206e6f74206578697374000000000000000000000000000081525060200191505060405180910390fd5b8188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600115156171ab838361635e565b1515141515617205576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f9534808b8b8b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156172f657600080fd5b505af115801561730a573d6000803e3d6000fd5b5050505060608a8a8a8a604051602001808060200180602001806020018481038452888882818152602001925080828437600081840152601f19601f820116905080830192505050848103835260018152602001807f2e000000000000000000000000000000000000000000000000000000000000008152506020018481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509750505050505050506040516020818303038152906040529050600087879050111561751a57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f5e1a458888846040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352868682818152602001925080828437600081840152601f19601f820116905080830192505050838103825284818151815260200191508051906020019080838360005b838110156174b2578082015181840152602081019050617497565b50505050905090810190601f1680156174df5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561750157600080fd5b505af1158015617515573d6000803e3d6000fd5b505050505b5050505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156175ab57600080fd5b505afa1580156175bf573d6000803e3d6000fd5b505050506040513d60208110156175d557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561766b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b806001151561767982618073565b15151415156176d3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b60018314806176e25750600283145b1515617756576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4f7065726174696f6e206e6f7420616c6c6f776564000000000000000000000081525060200191505060405180910390fd5b600080600185141561776f576002915060039050617782565b60028514156177815760039150600590505b5b600115156177d488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505083619386565b151514151561784b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6f7065726174696f6e206e6f7420616c6c6f776564000000000000000000000081525060200191505060405180910390fd5b6178f060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156178e45780601f106178b9576101008083540402835291602001916178e4565b820191906000526020600020905b8154815290600101906020018083116178c757829003601f168201915b505050505085846194c7565b156179d357600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166314f775f98888886040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f820116905080830192505050945050505050600060405180830381600087803b1580156179ba57600080fd5b505af11580156179ce573d6000803e3d6000fd5b505050505b50505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015617a6057600080fd5b505afa158015617a74573d6000803e3d6000fd5b505050506040513d6020811015617a8a57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515617b20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8060011515617b2e82618073565b1515141515617b88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc501468585898960046040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b158015617c8257600080fd5b505af1158015617c96573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d600688888888600060056040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184810384528b818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015617dd65780601f10617dab57610100808354040283529160200191617dd6565b820191906000526020600020905b815481529060010190602001808311617db957829003601f168201915b505084810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015617e5457600080fd5b505af1158015617e68573d6000803e3d6000fd5b50505050505050505050565b60608060606000600660076008600a60009054906101000a900460ff16838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015617f265780601f10617efb57610100808354040283529160200191617f26565b820191906000526020600020905b815481529060010190602001808311617f0957829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015617fc25780601f10617f9757610100808354040283529160200191617fc2565b820191906000526020600020905b815481529060010190602001808311617fa557829003601f168201915b50505050509250818054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561805e5780601f106180335761010080835404028352916020019161805e565b820191906000526020600020905b81548152906001019060200180831161804157829003601f168201915b50505050509150935093509350935090919293565b6000600760405160200180806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156181035780601f106180d857610100808354040283529160200191618103565b820191906000526020600020905b8154815290600101906020018083116180e657829003601f168201915b505092505050604051602081830303815290604052805190602001206000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381d66b23846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060006040518083038186803b1580156181d957600080fd5b505afa1580156181ed573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561821757600080fd5b81019080805164010000000081111561822f57600080fd5b8281019050602081018481111561824557600080fd5b815185600182028301116401000000008211171561826257600080fd5b50509291905050506040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156182ad578082015181840152602081019050618292565b50505050905090810190601f1680156182da5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120149050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561838157600080fd5b505afa158015618395573d6000803e3d6000fd5b505050506040513d60208110156183ab57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618441576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b8086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060011515618495838361635e565b15151415156184ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180619ece6022913960400191505060405180910390fd5b60018414806184fe5750600284145b806185095750600384145b1515618560576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180619e5b6025913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630cc5014687878b8b896040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018481526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b15801561865957600080fd5b505af115801561866d573d6000803e3d6000fd5b505050505050505050505050565b606080600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663014e6acc87876040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561873c57600080fd5b505afa158015618750573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561877a57600080fd5b81019080805164010000000081111561879257600080fd5b828101905060208101848111156187a857600080fd5b81518560018202830111640100000000821117156187c557600080fd5b505092919060200180516401000000008111156187e157600080fd5b828101905060208101848111156187f757600080fd5b815185600182028301116401000000008211171561881457600080fd5b50509291906020018051906020019092919080519060200190929190505050935093509350935092959194509250565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801515600a60009054906101000a900460ff161515141515618995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8787600691906189a6929190619db5565b508585600791906189b8929190619db5565b508383600891906189ca929190619db5565b5081600a60006101000a81548160ff0219169083151502179055505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e572515c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015618a7357600080fd5b505afa158015618a87573d6000803e3d6000fd5b505050506040513d6020811015618a9d57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515618b33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180619e806028913960400191505060405180910390fd5b6001801515600a60009054906101000a900460ff161515141515618bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e636f7272656374206e6574776f726b20626f6f742073746174757300000081525060200191505060405180910390fd5b8160011515618bcd82618073565b1515141515618c27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180619ea86026913960400191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98ac22d60068a8a8a8a8a60016040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184810384528b818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015618d625780601f10618d3757610100808354040283529160200191618d62565b820191906000526020600020905b815481529060010190602001808311618d4557829003601f168201915b505084810383528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b158015618de057600080fd5b505af1158015618df4573d6000803e3d6000fd5b50505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f9953de589896040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015618eb557600080fd5b505af1158015618ec9573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a97a440687878b8b6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015618fbe57600080fd5b505af1158015618fd2573d6000803e3d6000fd5b5050505060011515619028858a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506154ea565b151514151561909f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4f7065726174696f6e2063616e6e6f7420626520706572666f726d656400000081525060200191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e3483a9d858a8a600860016040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018481526020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156191fe5780601f106191d3576101008083540402835291602001916191fe565b820191906000526020600020905b8154815290600101906020018083116191e157829003601f168201915b5050975050505050505050600060405180830381600087803b15801561922357600080fd5b505af1158015619237573d6000803e3d6000fd5b505050505050505050505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c8642df8360026040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b838110156192f95780820151818401526020810190506192de565b50505050905090810190601f1680156193265780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561934457600080fd5b505afa158015619358573d6000803e3d6000fd5b505050506040513d602081101561936e57600080fd5b81019080805190602001909291905050509050919050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c8642df84846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561943957808201518184015260208101905061941e565b50505050905090810190601f1680156194665780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561948457600080fd5b505afa158015619498573d6000803e3d6000fd5b505050506040513d60208110156194ae57600080fd5b8101908080519060200190929190505050905092915050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b02138648585856040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156195ad578082015181840152602081019050619592565b50505050905090810190601f1680156195da5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156195fb57600080fd5b505af115801561960f573d6000803e3d6000fd5b505050506040513d602081101561962557600080fd5b810190808051906020019092919050505090509392505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ffe40d1d836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156196eb5780820151818401526020810190506196d0565b50505050905090810190601f1680156197185780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561973557600080fd5b505afa158015619749573d6000803e3d6000fd5b505050506040513d602081101561975f57600080fd5b81019080805190602001909291905050509050919050565b80156198c457600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635607395b84846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561985a57808201518184015260208101905061983f565b50505050905090810190601f1680156198875780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156198a757600080fd5b505af11580156198bb573d6000803e3d6000fd5b50505050619a07565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359cbd6fe84846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b838110156199a1578082015181840152602081019050619986565b50505050905090810190601f1680156199ce5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156199ee57600080fd5b505af1158015619a02573d6000803e3d6000fd5b505050505b505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663abf5739f8484619a5786619c27565b6040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015619aca578082015181840152602081019050619aaf565b50505050905090810190601f168015619af75780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b83811015619b30578082015181840152602081019050619b15565b50505050905090810190601f168015619b5d5780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015619b96578082015181840152602081019050619b7b565b50505050905090810190601f168015619bc35780820380516001836020036101000a031916815260200191505b50965050505050505060206040518083038186803b158015619be457600080fd5b505afa158015619bf8573d6000803e3d6000fd5b505050506040513d6020811015619c0e57600080fd5b8101908080519060200190929190505050905092915050565b6060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663177c8d8a836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015619cd3578082015181840152602081019050619cb8565b50505050905090810190601f168015619d005780820380516001836020036101000a031916815260200191505b509250505060006040518083038186803b158015619d1d57600080fd5b505afa158015619d31573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015619d5b57600080fd5b810190808051640100000000811115619d7357600080fd5b82810190506020810184811115619d8957600080fd5b8151856001820283011164010000000082111715619da657600080fd5b50509291905050509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10619df657803560ff1916838001178555619e24565b82800160010185558215619e24579182015b82811115619e23578235825591602001919060010190619e08565b5b509050619e319190619e35565b5090565b619e5791905b80821115619e53576000816000905550600101619e3b565b5090565b9056fe696e76616c696420616374696f6e2e206f7065726174696f6e206e6f7420616c6c6f77656463616e2062652063616c6c656420627920696e7465726661636520636f6e7472616374206f6e6c796163636f756e74206973206e6f742061206e6574776f726b2061646d696e206163636f756e746163636f756e74206973206e6f742061206f72672061646d696e206163636f756e74a165627a7a723058201cfc4043c31882758609d4d19ea314d7cb2a97d0aad47c021996fe1b795b5a1a0029 \ No newline at end of file diff --git a/permission/contract/gen/PermissionsInterface.abi b/permission/contract/gen/PermissionsInterface.abi new file mode 100644 index 0000000000..fc1e434141 --- /dev/null +++ b/permission/contract/gen/PermissionsInterface.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"getPermissionsImpl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateNodeStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"}],"name":"approveAdminRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nwAdminOrg","type":"string"},{"name":"_nwAdminRole","type":"string"},{"name":"_oAdminRole","type":"string"}],"name":"setPolicy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"},{"name":"_roleId","type":"string"}],"name":"assignAccountRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"}],"name":"approveBlacklistedAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enodeId","type":"string"}],"name":"addAdminNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_roleId","type":"string"}],"name":"assignAdminRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"updateNetworkBootStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNetworkBootStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pOrgId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_acct","type":"address"}],"name":"addAdminAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_permImplementation","type":"address"}],"name":"setPermImplementation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_access","type":"uint256"},{"name":"_voter","type":"bool"},{"name":"_admin","type":"bool"}],"name":"addNewRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"}],"name":"approveBlacklistedNodeRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"approveOrgStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"}],"name":"validateAccount","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_account","type":"address"}],"name":"approveOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"},{"name":"_action","type":"uint256"}],"name":"updateAccountStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"}],"name":"startBlacklistedNodeRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_account","type":"address"}],"name":"addOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"},{"name":"_orgId","type":"string"}],"name":"isOrgAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_breadth","type":"uint256"},{"name":"_depth","type":"uint256"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"}],"name":"removeRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_account","type":"address"}],"name":"startBlacklistedAccountRecovery","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"}],"name":"addNode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_action","type":"uint256"}],"name":"updateOrgStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"isNetworkAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getPendingOp","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permImplUpgradeable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}] \ No newline at end of file diff --git a/permission/contract/gen/PermissionsInterface.bin b/permission/contract/gen/PermissionsInterface.bin new file mode 100644 index 0000000000..7aa9859957 --- /dev/null +++ b/permission/contract/gen/PermissionsInterface.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506040516020806138138339810180604052602081101561003057600080fd5b810190808051906020019092919050505080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050613781806100926000396000f3fe608060405234801561001057600080fd5b50600436106101ec576000357c0100000000000000000000000000000000000000000000000000000000900480635adbfa7a116101215780639bd38101116100bf578063a97a44061161008e578063a97a44061461123b578063bb3b6e8014611309578063d1aa0c201461138c578063f346a3a7146113e8576101ec565b80639bd3810114610feb578063a5843f081461109c578063a6343012146110d4578063a97914bf146111a2576101ec565b80637e461258116100fb5780637e46125814610c9e57806384b7a84a14610d8c5780638cb58ef314610e2f5780638f362a3e14610efd576101ec565b80635adbfa7a14610a9c5780635be9672c14610b6a5780636b568d7614610bed576101ec565b806343de646c1161018e5780634cff819e116101685780634cff819e146108015780634fe57e7a14610924578063511bbd9f1461096857806351f604c3146109ac576101ec565b806343de646c146106cf57806344478e79146107bd5780634cbfa82e146107df576101ec565b80631b610220116101ca5780631b610220146103ac5780632f7f0a12146104cf5780633e239b23146105bd5780633f25c28814610656576101ec565b806303ed6933146101f15780630cc501461461023b57806316724c4414610313575b600080fd5b6101f9611580565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103116004803603606081101561025157600080fd5b810190808035906020019064010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460018302840111640100000000831117156102a257600080fd5b9091929391929390803590602001906401000000008111156102c357600080fd5b8201836020820111156102d557600080fd5b803590602001918460018302840111640100000000831117156102f757600080fd5b9091929391929390803590602001909291905050506115a9565b005b6103aa6004803603604081101561032957600080fd5b810190808035906020019064010000000081111561034657600080fd5b82018360208201111561035857600080fd5b8035906020019184600183028401116401000000008311171561037a57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116f4565b005b6104cd600480360360608110156103c257600080fd5b81019080803590602001906401000000008111156103df57600080fd5b8201836020820111156103f157600080fd5b8035906020019184600183028401116401000000008311171561041357600080fd5b90919293919293908035906020019064010000000081111561043457600080fd5b82018360208201111561044657600080fd5b8035906020019184600183028401116401000000008311171561046857600080fd5b90919293919293908035906020019064010000000081111561048957600080fd5b82018360208201111561049b57600080fd5b803590602001918460018302840111640100000000831117156104bd57600080fd5b9091929391929390505050611835565b005b6105bb600480360360608110156104e557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561052257600080fd5b82018360208201111561053457600080fd5b8035906020019184600183028401116401000000008311171561055657600080fd5b90919293919293908035906020019064010000000081111561057757600080fd5b82018360208201111561058957600080fd5b803590602001918460018302840111640100000000831117156105ab57600080fd5b9091929391929390505050611979565b005b610654600480360360408110156105d357600080fd5b81019080803590602001906401000000008111156105f057600080fd5b82018360208201111561060257600080fd5b8035906020019184600183028401116401000000008311171561062457600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611af0565b005b6106cd6004803603602081101561066c57600080fd5b810190808035906020019064010000000081111561068957600080fd5b82018360208201111561069b57600080fd5b803590602001918460018302840111640100000000831117156106bd57600080fd5b9091929391929390505050611c31565b005b6107bb600480360360608110156106e557600080fd5b810190808035906020019064010000000081111561070257600080fd5b82018360208201111561071457600080fd5b8035906020019184600183028401116401000000008311171561073657600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561077757600080fd5b82018360208201111561078957600080fd5b803590602001918460018302840111640100000000831117156107ab57600080fd5b9091929391929390505050611d09565b005b6107c5611e80565b604051808215151515815260200191505060405180910390f35b6107e7611f47565b604051808215151515815260200191505060405180910390f35b6109226004803603606081101561081757600080fd5b810190808035906020019064010000000081111561083457600080fd5b82018360208201111561084657600080fd5b8035906020019184600183028401116401000000008311171561086857600080fd5b90919293919293908035906020019064010000000081111561088957600080fd5b82018360208201111561089b57600080fd5b803590602001918460018302840111640100000000831117156108bd57600080fd5b9091929391929390803590602001906401000000008111156108de57600080fd5b8201836020820111156108f057600080fd5b8035906020019184600183028401116401000000008311171561091257600080fd5b909192939192939050505061200c565b005b6109666004803603602081101561093a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612184565b005b6109aa6004803603602081101561097e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061225b565b005b610a9a600480360360a08110156109c257600080fd5b81019080803590602001906401000000008111156109df57600080fd5b8201836020820111156109f157600080fd5b80359060200191846001830284011164010000000083111715610a1357600080fd5b909192939192939080359060200190640100000000811115610a3457600080fd5b820183602082011115610a4657600080fd5b80359060200191846001830284011164010000000083111715610a6857600080fd5b909192939192939080359060200190929190803515159060200190929190803515159060200190929190505050612363565b005b610b6860048036036040811015610ab257600080fd5b8101908080359060200190640100000000811115610acf57600080fd5b820183602082011115610ae157600080fd5b80359060200191846001830284011164010000000083111715610b0357600080fd5b909192939192939080359060200190640100000000811115610b2457600080fd5b820183602082011115610b3657600080fd5b80359060200191846001830284011164010000000083111715610b5857600080fd5b90919293919293905050506124c8565b005b610beb60048036036040811015610b8057600080fd5b8101908080359060200190640100000000811115610b9d57600080fd5b820183602082011115610baf57600080fd5b80359060200191846001830284011164010000000083111715610bd157600080fd5b90919293919293908035906020019092919050505061260a565b005b610c8460048036036040811015610c0357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610c4057600080fd5b820183602082011115610c5257600080fd5b80359060200191846001830284011164010000000083111715610c7457600080fd5b909192939192939050505061271f565b604051808215151515815260200191505060405180910390f35b610d8a60048036036060811015610cb457600080fd5b8101908080359060200190640100000000811115610cd157600080fd5b820183602082011115610ce357600080fd5b80359060200191846001830284011164010000000083111715610d0557600080fd5b909192939192939080359060200190640100000000811115610d2657600080fd5b820183602082011115610d3857600080fd5b80359060200191846001830284011164010000000083111715610d5a57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612853565b005b610e2d60048036036060811015610da257600080fd5b8101908080359060200190640100000000811115610dbf57600080fd5b820183602082011115610dd157600080fd5b80359060200191846001830284011164010000000083111715610df357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506129ca565b005b610efb60048036036040811015610e4557600080fd5b8101908080359060200190640100000000811115610e6257600080fd5b820183602082011115610e7457600080fd5b80359060200191846001830284011164010000000083111715610e9657600080fd5b909192939192939080359060200190640100000000811115610eb757600080fd5b820183602082011115610ec957600080fd5b80359060200191846001830284011164010000000083111715610eeb57600080fd5b9091929391929390505050612b14565b005b610fe960048036036060811015610f1357600080fd5b8101908080359060200190640100000000811115610f3057600080fd5b820183602082011115610f4257600080fd5b80359060200191846001830284011164010000000083111715610f6457600080fd5b909192939192939080359060200190640100000000811115610f8557600080fd5b820183602082011115610f9757600080fd5b80359060200191846001830284011164010000000083111715610fb957600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c56565b005b6110826004803603604081101561100157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561103e57600080fd5b82018360208201111561105057600080fd5b8035906020019184600183028401116401000000008311171561107257600080fd5b9091929391929390505050612dcd565b604051808215151515815260200191505060405180910390f35b6110d2600480360360408110156110b257600080fd5b810190808035906020019092919080359060200190929190505050612f01565b005b6111a0600480360360408110156110ea57600080fd5b810190808035906020019064010000000081111561110757600080fd5b82018360208201111561111957600080fd5b8035906020019184600183028401116401000000008311171561113b57600080fd5b90919293919293908035906020019064010000000081111561115c57600080fd5b82018360208201111561116e57600080fd5b8035906020019184600183028401116401000000008311171561119057600080fd5b9091929391929390505050612fb5565b005b611239600480360360408110156111b857600080fd5b81019080803590602001906401000000008111156111d557600080fd5b8201836020820111156111e757600080fd5b8035906020019184600183028401116401000000008311171561120957600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506130f7565b005b6113076004803603604081101561125157600080fd5b810190808035906020019064010000000081111561126e57600080fd5b82018360208201111561128057600080fd5b803590602001918460018302840111640100000000831117156112a257600080fd5b9091929391929390803590602001906401000000008111156112c357600080fd5b8201836020820111156112d557600080fd5b803590602001918460018302840111640100000000831117156112f757600080fd5b9091929391929390505050613238565b005b61138a6004803603604081101561131f57600080fd5b810190808035906020019064010000000081111561133c57600080fd5b82018360208201111561134e57600080fd5b8035906020019184600183028401116401000000008311171561137057600080fd5b90919293919293908035906020019092919050505061337a565b005b6113ce600480360360208110156113a257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061348f565b604051808215151515815260200191505060405180910390f35b61145f600480360360208110156113fe57600080fd5b810190808035906020019064010000000081111561141b57600080fd5b82018360208201111561142d57600080fd5b8035906020019184600183028401116401000000008311171561144f57600080fd5b909192939192939050505061358d565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b838110156114db5780820151818401526020810190506114c0565b50505050905090810190601f1680156115085780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b83811015611541578082015181840152602081019050611526565b50505050905090810190601f16801561156e5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dbfad7118686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b1580156116d557600080fd5b505af11580156116e9573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166388843041848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561181857600080fd5b505af115801561182c573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b6102208787878787876040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018060200184810384528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509950505050505050505050600060405180830381600087803b15801561195957600080fd5b505af115801561196d573d6000803e3d6000fd5b50505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638baa81918686868686336040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015611ad157600080fd5b505af1158015611ae5573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b20f45f848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611c1457600080fd5b505af1158015611c28573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633f25c28883836040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015611ced57600080fd5b505af1158015611d01573d6000803e3d6000fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663404bf3eb8686868686336040518763ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015611e6157600080fd5b505af1158015611e75573d6000803e3d6000fd5b505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166344478e796040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611f0757600080fd5b505af1158015611f1b573d6000803e3d6000fd5b505050506040513d6020811015611f3157600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634cbfa82e6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611fcc57600080fd5b505afa158015611fe0573d6000803e3d6000fd5b505050506040513d6020811015611ff657600080fd5b8101908080519060200190929190505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a64d2860878787878787336040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184810384528b8b82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508481038252878782818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b15801561216457600080fd5b505af1158015612178573d6000803e3d6000fd5b50505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634fe57e7a826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561224057600080fd5b505af1158015612254573d6000803e3d6000fd5b5050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631b04c27688888888888888336040518963ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200187815260200186151515158152602001851515151581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183810383528b8b82818152602001925080828437600081840152601f19601f8201169050808301925050508381038252898982818152602001925080828437600081840152601f19601f8201169050808301925050509a5050505050505050505050600060405180830381600087803b1580156124a757600080fd5b505af11580156124bb573d6000803e3d6000fd5b5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663655a8ef585858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156125ec57600080fd5b505af1158015612600573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b5546564848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561270257600080fd5b505af1158015612716573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b568d768585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d602081101561283957600080fd5b810190808051906020019092919050505090509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633bc07dea8686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b1580156129ab57600080fd5b505af11580156129bf573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166304e81f1e85858585336040518663ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b158015612af657600080fd5b505af1158015612b0a573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c3dc8e0985858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b158015612c3857600080fd5b505af1158015612c4c573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f922f8028686868686336040518763ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352898982818152602001925080828437600081840152601f19601f8201169050808301925050508381038252878782818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612dae57600080fd5b505af1158015612dc2573d6000803e3d6000fd5b505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639bd381018585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060206040518083038186803b158015612ebd57600080fd5b505afa158015612ed1573d6000803e3d6000fd5b505050506040513d6020811015612ee757600080fd5b810190808051906020019092919050505090509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a5843f0883836040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182815260200192505050600060405180830381600087803b158015612f9957600080fd5b505af1158015612fad573d6000803e3d6000fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ca5adbe85858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156130d957600080fd5b505af11580156130ed573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c249912848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561321b57600080fd5b505af115801561322f573d6000803e3d6000fd5b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359a260a385858585336040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508381038252868682818152602001925080828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b15801561335c57600080fd5b505af1158015613370573d6000803e3d6000fd5b5050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633cf5f33b848484336040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561347257600080fd5b505af1158015613486573d6000803e3d6000fd5b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1aa0c20836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561354b57600080fd5b505afa15801561355f573d6000803e3d6000fd5b505050506040513d602081101561357557600080fd5b81019080805190602001909291905050509050919050565b6060806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f346a3a787876040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060006040518083038186803b15801561364d57600080fd5b505afa158015613661573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250608081101561368b57600080fd5b8101908080516401000000008111156136a357600080fd5b828101905060208101848111156136b957600080fd5b81518560018202830111640100000000821117156136d657600080fd5b505092919060200180516401000000008111156136f257600080fd5b8281019050602081018481111561370857600080fd5b815185600182028301116401000000008211171561372557600080fd5b5050929190602001805190602001909291908051906020019092919050505093509350935093509295919450925056fea165627a7a7230582049eecad3069ea93138ffdb59f1b6803feaa6cde89ea4ef7956f533e671354e340029 \ No newline at end of file diff --git a/permission/contract/gen/PermissionsUpgradable.abi b/permission/contract/gen/PermissionsUpgradable.abi new file mode 100644 index 0000000000..035f83a651 --- /dev/null +++ b/permission/contract/gen/PermissionsUpgradable.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"getPermImpl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_proposedImpl","type":"address"}],"name":"confirmImplChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getGuardian","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPermInterface","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_permInterface","type":"address"},{"name":"_permImpl","type":"address"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_guardian","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}] \ No newline at end of file diff --git a/permission/contract/gen/PermissionsUpgradable.bin b/permission/contract/gen/PermissionsUpgradable.bin new file mode 100644 index 0000000000..1869a3cba5 --- /dev/null +++ b/permission/contract/gen/PermissionsUpgradable.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50604051602080610b2d8339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260146101000a81548160ff02191690831515021790555050610a81806100ac6000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c0100000000000000000000000000000000000000000000000000000000900480630e32cf901461007957806322bcb39a146100c3578063a75b87d214610107578063e572515c14610151578063f09a40161461019b575b600080fd5b6100816101ff565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610105600480360360208110156100d957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610229565b005b61010f61053c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610159610565565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101fd600480360360408110156101b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061058f565b005b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b60608060606000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc9ba6fa6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561037857600080fd5b505afa15801561038c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060808110156103b657600080fd5b8101908080516401000000008111156103ce57600080fd5b828101905060208101848111156103e457600080fd5b815185600182028301116401000000008211171561040157600080fd5b5050929190602001805164010000000081111561041d57600080fd5b8281019050602081018481111561043357600080fd5b815185600182028301116401000000008211171561045057600080fd5b5050929190602001805164010000000081111561046c57600080fd5b8281019050602081018481111561048257600080fd5b815185600182028301116401000000008211171561049f57600080fd5b50509291906020018051906020019092919050505093509350935093506104c985858585856107a4565b84600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610535600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661097d565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600260149054906101000a900460ff161515156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f63616e206265206578656375746564206f6e6c79206f6e63650000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610785600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661097d565b6001600260146101000a81548160ff0219169083151502179055505050565b8473ffffffffffffffffffffffffffffffffffffffff1663f5ad584a858585856040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b83811015610841578082015181840152602081019050610826565b50505050905090810190601f16801561086e5780820380516001836020036101000a031916815260200191505b50848103835287818151815260200191508051906020019080838360005b838110156108a757808201518184015260208101905061088c565b50505050905090810190601f1680156108d45780820380516001836020036101000a031916815260200191505b50848103825286818151815260200191508051906020019080838360005b8381101561090d5780820151818401526020810190506108f2565b50505050905090810190601f16801561093a5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561095e57600080fd5b505af1158015610972573d6000803e3d6000fd5b505050505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663511bbd9f826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015610a3a57600080fd5b505af1158015610a4e573d6000803e3d6000fd5b505050505056fea165627a7a72305820378cf538b83ea9abe4413391f6284a8f7e800144d9df63dcbba67da0f58949500029 \ No newline at end of file diff --git a/permission/contract/gen/RoleManager.abi b/permission/contract/gen/RoleManager.abi new file mode 100644 index 0000000000..28e7e76ae3 --- /dev/null +++ b/permission/contract/gen/RoleManager.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"}],"name":"getRoleDetails","outputs":[{"name":"roleId","type":"string"},{"name":"orgId","type":"string"},{"name":"accessType","type":"uint256"},{"name":"voter","type":"bool"},{"name":"admin","type":"bool"},{"name":"active","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_baseAccess","type":"uint256"},{"name":"_isVoter","type":"bool"},{"name":"_isAdmin","type":"bool"}],"name":"addRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfRoles","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_rIndex","type":"uint256"}],"name":"getRoleDetailsFromIndex","outputs":[{"name":"roleId","type":"string"},{"name":"orgId","type":"string"},{"name":"accessType","type":"uint256"},{"name":"voter","type":"bool"},{"name":"admin","type":"bool"},{"name":"active","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"}],"name":"removeRole","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_ultParent","type":"string"}],"name":"roleExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_ultParent","type":"string"}],"name":"isAdminRole","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_roleId","type":"string"},{"name":"_orgId","type":"string"},{"name":"_ultParent","type":"string"}],"name":"isVoterRole","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_roleId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_baseAccess","type":"uint256"},{"indexed":false,"name":"_isVoter","type":"bool"},{"indexed":false,"name":"_isAdmin","type":"bool"}],"name":"RoleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_roleId","type":"string"},{"indexed":false,"name":"_orgId","type":"string"}],"name":"RoleRevoked","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/RoleManager.bin b/permission/contract/gen/RoleManager.bin new file mode 100644 index 0000000000..6fc00b0d5d --- /dev/null +++ b/permission/contract/gen/RoleManager.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506040516020806129598339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506128c8806100916000396000f3fe608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063a634301211610078578063a634301214610552578063abf5739f14610620578063be322e5414610821578063deb16ba71461095c576100a5565b80631870aba3146100aa5780637b7135791461028557806387f55d31146103f9578063a451d4a814610417575b600080fd5b610176600480360360408110156100c057600080fd5b81019080803590602001906401000000008111156100dd57600080fd5b8201836020820111156100ef57600080fd5b8035906020019184600183028401116401000000008311171561011157600080fd5b90919293919293908035906020019064010000000081111561013257600080fd5b82018360208201111561014457600080fd5b8035906020019184600183028401116401000000008311171561016657600080fd5b9091929391929390505050610a97565b604051808060200180602001878152602001861515151581526020018515151515815260200184151515158152602001838103835289818151815260200191508051906020019080838360005b838110156101de5780820151818401526020810190506101c3565b50505050905090810190601f16801561020b5780820380516001836020036101000a031916815260200191505b50838103825288818151815260200191508051906020019080838360005b83811015610244578082015181840152602081019050610229565b50505050905090810190601f1680156102715780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b6103f7600480360360a081101561029b57600080fd5b81019080803590602001906401000000008111156102b857600080fd5b8201836020820111156102ca57600080fd5b803590602001918460018302840111640100000000831117156102ec57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561034f57600080fd5b82018360208201111561036157600080fd5b8035906020019184600183028401116401000000008311171561038357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803515159060200190929190803515159060200190929190505050610e9b565b005b6104016114db565b6040518082815260200191505060405180910390f35b6104436004803603602081101561042d57600080fd5b81019080803590602001909291905050506114e8565b604051808060200180602001878152602001861515151581526020018515151515815260200184151515158152602001838103835289818151815260200191508051906020019080838360005b838110156104ab578082015181840152602081019050610490565b50505050905090810190601f1680156104d85780820380516001836020036101000a031916815260200191505b50838103825288818151815260200191508051906020019080838360005b838110156105115780820151818401526020810190506104f6565b50505050905090810190601f16801561053e5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b61061e6004803603604081101561056857600080fd5b810190808035906020019064010000000081111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111640100000000831117156105b957600080fd5b9091929391929390803590602001906401000000008111156105da57600080fd5b8201836020820111156105ec57600080fd5b8035906020019184600183028401116401000000008311171561060e57600080fd5b9091929391929390505050611729565b005b6108076004803603606081101561063657600080fd5b810190808035906020019064010000000081111561065357600080fd5b82018360208201111561066557600080fd5b8035906020019184600183028401116401000000008311171561068757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156106ea57600080fd5b8201836020820111156106fc57600080fd5b8035906020019184600183028401116401000000008311171561071e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561078157600080fd5b82018360208201111561079357600080fd5b803590602001918460018302840111640100000000831117156107b557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611b08565b604051808215151515815260200191505060405180910390f35b6109426004803603606081101561083757600080fd5b810190808035906020019064010000000081111561085457600080fd5b82018360208201111561086657600080fd5b8035906020019184600183028401116401000000008311171561088857600080fd5b9091929391929390803590602001906401000000008111156108a957600080fd5b8201836020820111156108bb57600080fd5b803590602001918460018302840111640100000000831117156108dd57600080fd5b9091929391929390803590602001906401000000008111156108fe57600080fd5b82018360208201111561091057600080fd5b8035906020019184600183028401116401000000008311171561093257600080fd5b9091929391929390505050611dc6565b604051808215151515815260200191505060405180910390f35b610a7d6004803603606081101561097257600080fd5b810190808035906020019064010000000081111561098f57600080fd5b8201836020820111156109a157600080fd5b803590602001918460018302840111640100000000831117156109c357600080fd5b9091929391929390803590602001906401000000008111156109e457600080fd5b8201836020820111156109f657600080fd5b80359060200191846001830284011164010000000083111715610a1857600080fd5b909192939192939080359060200190640100000000811115610a3957600080fd5b820183602082011115610a4b57600080fd5b80359060200191846001830284011164010000000083111715610a6d57600080fd5b9091929391929390505050612252565b604051808215151515815260200191505060405180910390f35b606080600080600080610b438a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506020604051908101604052806000815250611b08565b1515610bc757898960008060008085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509450909192939450602060405190810160405280600081525093929190839350955095509550955095509550610e8e565b6000610c5b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b9050600181815481101515610c6c57fe5b9060005260206000209060040201600001600182815481101515610c8c57fe5b9060005260206000209060040201600101600183815481101515610cac57fe5b906000526020600020906004020160020154600184815481101515610ccd57fe5b906000526020600020906004020160030160009054906101000a900460ff16600185815481101515610cfb57fe5b906000526020600020906004020160030160019054906101000a900460ff16600186815481101515610d2957fe5b906000526020600020906004020160030160029054906101000a900460ff16858054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ddd5780601f10610db257610100808354040283529160200191610ddd565b820191906000526020600020905b815481529060010190602001808311610dc057829003601f168201915b50505050509550848054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e795780601f10610e4e57610100808354040283529160200191610e79565b820191906000526020600020905b815481529060010190602001808311610e5c57829003601f168201915b50505050509450965096509650965096509650505b9499939850945094509450565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015610f1e57600080fd5b505afa158015610f32573d6000803e3d6000fd5b505050506040513d6020811015610f4857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561104a57808201518184015260208101905061102f565b50505050905090810190601f1680156110775780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156110b0578082015181840152602081019050611095565b50505050905090810190601f1680156110dd5780820380516001836020036101000a031916815260200191505b509450505050506040516020818303038152906040528051906020012081526020019081526020016000205414151561117e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f726f6c652065786973747320666f7220746865206f726700000000000000000081525060200191505060405180910390fd5b600360008154809291906001019190505550600354600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b838110156111e05780820151818401526020810190506111c5565b50505050905090810190601f16801561120d5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561124657808201518184015260208101905061122b565b50505050905090810190601f1680156112735780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600160c06040519081016040528087815260200186815260200185815260200184151581526020018315158152602001600115158152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000190805190602001906113209291906127f7565b50602082015181600101908051906020019061133d9291906127f7565b506040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548160ff02191690831515021790555060a08201518160030160026101000a81548160ff0219169083151502179055505050507fefa5bc1bedbee25b04b00855c15a0c180ecb4a2440d4d08296e49561655e2b1c85858585856040518080602001806020018681526020018515151515815260200184151515158152602001838103835288818151815260200191508051906020019080838360005b8381101561142f578082015181840152602081019050611414565b50505050905090810190601f16801561145c5780820380516001836020036101000a031916815260200191505b50838103825287818151815260200191508051906020019080838360005b8381101561149557808201518184015260208101905061147a565b50505050905090810190601f1680156114c25780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15050505050565b6000600180549050905090565b60608060008060008060018781548110151561150057fe5b906000526020600020906004020160000160018881548110151561152057fe5b906000526020600020906004020160010160018981548110151561154057fe5b90600052602060002090600402016002015460018a81548110151561156157fe5b906000526020600020906004020160030160009054906101000a900460ff1660018b81548110151561158f57fe5b906000526020600020906004020160030160019054906101000a900460ff1660018c8154811015156115bd57fe5b906000526020600020906004020160030160029054906101000a900460ff16858054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116715780601f1061164657610100808354040283529160200191611671565b820191906000526020600020905b81548152906001019060200180831161165457829003601f168201915b50505050509550848054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561170d5780601f106116e25761010080835404028352916020019161170d565b820191906000526020600020905b8154815290600101906020018083116116f057829003601f168201915b5050505050945095509550955095509550955091939550919395565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156117ac57600080fd5b505afa1580156117c0573d6000803e3d6000fd5b505050506040513d60208110156117d657600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611889576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600060026000868686866040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050604051602081830303815290604052805190602001208152602001908152602001600020541415151561199b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f726f6c6520646f6573206e6f742065786973740000000000000000000000000081525060200191505060405180910390fd5b6000611a2f85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90506000600182815481101515611a4257fe5b906000526020600020906004020160030160026101000a81548160ff0219169083151502179055507f1196059dd83524bf989fd94bb65808c09dbea2ab791fb6bfa87a0e0aa64b2ea6858585856040518080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a15050505050565b6000806000600260008787604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611b5a578082015181840152602081019050611b3f565b50505050905090810190601f168015611b875780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611bc0578082015181840152602081019050611ba5565b50505050905090810190601f168015611bed5780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002054141515611c6257611c2a85856126de565b9050600181815481101515611c3b57fe5b906000526020600020906004020160030160029054906101000a900460ff16915050611dbf565b6000600260008786604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611cb1578082015181840152602081019050611c96565b50505050905090810190601f168015611cde5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611d17578082015181840152602081019050611cfc565b50505050905090810190601f168015611d445780820380516001836020036101000a031916815260200191505b5094505050505060405160208183030381529060405280519060200120815260200190815260200160002054141515611db957611d8185846126de565b9050600181815481101515611d9257fe5b906000526020600020906004020160030160029054906101000a900460ff16915050611dbf565b60009150505b9392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611e4b57600080fd5b505afa158015611e5f573d6000803e3d6000fd5b505050506040513d6020811015611e7557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611fff87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b08565b151561200e5760009050612248565b600080600260008a8a8a8a6040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f82011690508083019250505096505050505050506040516020818303038152906040528051906020012081526020019081526020016000205414151561214b5761214488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90506121e0565b6121dd88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90505b6001818154811015156121ef57fe5b906000526020600020906004020160030160029054906101000a900460ff168015612244575060018181548110151561222457fe5b906000526020600020906004020160030160019054906101000a900460ff165b9150505b9695505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156122d757600080fd5b505afa1580156122eb573d6000803e3d6000fd5b505050506040513d602081101561230157600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b61248b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b08565b151561249a57600090506126d4565b600080600260008a8a8a8a6040516020018080602001806020018381038352878782818152602001925080828437600081840152601f19601f8201169050808301925050508381038252858582818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050604051602081830303815290604052805190602001208152602001908152602001600020541415156125d7576125d088888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b905061266c565b61266988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506126de565b90505b60018181548110151561267b57fe5b906000526020600020906004020160030160029054906101000a900460ff1680156126d057506001818154811015156126b057fe5b906000526020600020906004020160030160009054906101000a900460ff165b9150505b9695505050505050565b60006001600260008585604051602001808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561272f578082015181840152602081019050612714565b50505050905090810190601f16801561275c5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561279557808201518184015260208101905061277a565b50505050905090810190601f1680156127c25780820380516001836020036101000a031916815260200191505b509450505050506040516020818303038152906040528051906020012081526020019081526020016000205403905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061283857805160ff1916838001178555612866565b82800160010185558215612866579182015b8281111561286557825182559160200191906001019061284a565b5b5090506128739190612877565b5090565b61289991905b8082111561289557600081600090555060010161287d565b5090565b9056fea165627a7a7230582006ce3e54be3a54da4e284827f5291f19d7bc4a8fa63cfe3ce43f1e50c45ba2f00029 \ No newline at end of file diff --git a/permission/contract/gen/VoterManager.abi b/permission/contract/gen/VoterManager.abi new file mode 100644 index 0000000000..10c875209b --- /dev/null +++ b/permission/contract/gen/VoterManager.abi @@ -0,0 +1 @@ +[{"constant":true,"inputs":[{"name":"_orgId","type":"string"}],"name":"getPendingOpDetails","outputs":[{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_vAccount","type":"address"}],"name":"addVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_vAccount","type":"address"}],"name":"deleteVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_authOrg","type":"string"},{"name":"_vAccount","type":"address"},{"name":"_pendingOp","type":"uint256"}],"name":"processVote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_authOrg","type":"string"},{"name":"_orgId","type":"string"},{"name":"_enodeId","type":"string"},{"name":"_account","type":"address"},{"name":"_pendingOp","type":"uint256"}],"name":"addVotingItem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_permUpgradable","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_vAccount","type":"address"}],"name":"VoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_vAccount","type":"address"}],"name":"VoterDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"VotingItemAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"VoteProcessed","type":"event"}] \ No newline at end of file diff --git a/permission/contract/gen/VoterManager.bin b/permission/contract/gen/VoterManager.bin new file mode 100644 index 0000000000..327ba251ba --- /dev/null +++ b/permission/contract/gen/VoterManager.bin @@ -0,0 +1 @@ +6080604052600060035534801561001557600080fd5b506040516020806129498339810180604052602081101561003557600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506128b3806100966000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c010000000000000000000000000000000000000000000000000000000090048063014e6acc146100795780635607395b1461021157806359cbd6fe146102aa578063b021386414610343578063e98ac22d146103fe575b600080fd5b6100f06004803603602081101561008f57600080fd5b81019080803590602001906401000000008111156100ac57600080fd5b8201836020820111156100be57600080fd5b803590602001918460018302840111640100000000831117156100e057600080fd5b909192939192939050505061054b565b6040518080602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838103835287818151815260200191508051906020019080838360005b8381101561016c578082015181840152602081019050610151565b50505050905090810190601f1680156101995780820380516001836020036101000a031916815260200191505b50838103825286818151815260200191508051906020019080838360005b838110156101d25780820151818401526020810190506101b7565b50505050905090810190601f1680156101ff5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b6102a86004803603604081101561022757600080fd5b810190808035906020019064010000000081111561024457600080fd5b82018360208201111561025657600080fd5b8035906020019184600183028401116401000000008311171561027857600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108fa565b005b610341600480360360408110156102c057600080fd5b81019080803590602001906401000000008111156102dd57600080fd5b8201836020820111156102ef57600080fd5b8035906020019184600183028401116401000000008311171561031157600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611336565b005b6103e46004803603606081101561035957600080fd5b810190808035906020019064010000000081111561037657600080fd5b82018360208201111561038857600080fd5b803590602001918460018302840111640100000000831117156103aa57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611728565b604051808215151515815260200191505060405180910390f35b610549600480360360a081101561041457600080fd5b810190808035906020019064010000000081111561043157600080fd5b82018360208201111561044357600080fd5b8035906020019184600183028401116401000000008311171561046557600080fd5b90919293919293908035906020019064010000000081111561048657600080fd5b82018360208201111561049857600080fd5b803590602001918460018302840111640100000000831117156104ba57600080fd5b9091929391929390803590602001906401000000008111156104db57600080fd5b8201836020820111156104ed57600080fd5b8035906020019184600183028401116401000000008311171561050f57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e0a565b005b6060806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156105d457600080fd5b505afa1580156105e8573d6000803e3d6000fd5b505050506040513d60208110156105fe57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600061070087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b905060018181548110151561071157fe5b90600052602060002090600b020160040160000160018281548110151561073457fe5b90600052602060002090600b020160040160010160018381548110151561075757fe5b90600052602060002090600b020160040160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018481548110151561079b57fe5b90600052602060002090600b020160040160030154838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108455780601f1061081a57610100808354040283529160200191610845565b820191906000526020600020905b81548152906001019060200180831161082857829003601f168201915b50505050509350828054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108e15780601f106108b6576101008083540402835291602001916108e1565b820191906000526020600020905b8154815290600101906020018083116108c457829003601f168201915b5050505050925094509450945094505092959194509250565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561097d57600080fd5b505afa158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b600060026000858560405160200180806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509350505050604051602081830303815290604052805190602001208152602001908152602001600020541415610e815760036000815480929190600101919050555060035460026000858560405160200180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405160208183030381529060405280519060200120815260200190815260200160002081905550600060018054809190600101610b5c919061258c565b90508383600183815481101515610b6f57fe5b90600052602060002090600b02016000019190610b8d9291906125be565b5060018082815481101515610b9e57fe5b90600052602060002090600b02016001018190555060018082815481101515610bc357fe5b90600052602060002090600b0201600201819055506000600182815481101515610be957fe5b90600052602060002090600b0201600301819055506020604051908101604052806000815250600182815481101515610c1e57fe5b90600052602060002090600b02016004016000019080519060200190610c4592919061263e565b506020604051908101604052806000815250600182815481101515610c6657fe5b90600052602060002090600b02016004016001019080519060200190610c8d92919061263e565b506000600182815481101515610c9f57fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600182815481101515610d0257fe5b90600052602060002090600b020160040160030181905550600181815481101515610d2957fe5b90600052602060002090600b020160010154600182815481101515610d4a57fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600181815481101515610dab57fe5b90600052602060002090600b020160080160408051908101604052808473ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525090806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050505061129a565b6000610ed084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b90506000600182815481101515610ee357fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156110fe57600181815481101515610f4757fe5b90600052602060002090600b020160010160008154809291906001019190505550600181815481101515610f7757fe5b90600052602060002090600b020160010154600182815481101515610f9857fe5b90600052602060002090600b020160090160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600181815481101515610ff957fe5b90600052602060002090600b020160080160408051908101604052808473ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525090806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050506001818154811015156110d857fe5b90600052602060002090600b020160020160008154809291906001019190505550611298565b600061114e85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846123fe565b90506001151560018381548110151561116357fe5b90600052602060002090600b02016008018281548110151561118157fe5b9060005260206000200160000160149054906101000a900460ff16151514151515611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f616c7265616479206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b6001808381548110151561122457fe5b90600052602060002090600b02016008018281548110151561124257fe5b9060005260206000200160000160146101000a81548160ff02191690831515021790555060018281548110151561127557fe5b90600052602060002090600b020160020160008154809291906001019190505550505b505b7f424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d3457483838360405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a1505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156113b957600080fd5b505afa1580156113cd573d6000803e3d6000fd5b505050506040513d60208110156113e357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081600115156114ea8383612475565b1515141515611561576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6d757374206265206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b60006115b086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b9050600061160287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050866123fe565b905060018281548110151561161357fe5b90600052602060002090600b02016002016000815480929190600190039190505550600060018381548110151561164657fe5b90600052602060002090600b02016008018281548110151561166457fe5b9060005260206000200160000160146101000a81548160ff0219169083151502179055507f654cd85d9b2abaf3affef0a047625d088e6e4d0448935c9b5016b5f5aa0ca3b687878760405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a150505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156117ad57600080fd5b505afa1580156117c1573d6000803e3d6000fd5b505050506040513d60208110156117d757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505083600115156118de8383612475565b1515141515611955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6d757374206265206120766f746572000000000000000000000000000000000081525060200191505060405180910390fd5b600115156119a788888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086612554565b1515141515611a1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6e6f7468696e6720746f20617070726f7665000000000000000000000000000081525060200191505060405180910390fd5b6000611a6d88888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b905060011515600182815481101515611a8257fe5b90600052602060002090600b0201600a01600083815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514151515611b67576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f63616e6e6f7420646f75626c6520766f7465000000000000000000000000000081525060200191505060405180910390fd5b600181815481101515611b7657fe5b90600052602060002090600b02016003016000815480929190600101919050555060018082815481101515611ba757fe5b90600052602060002090600b0201600a01600083815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f87999b54e45aa02834a1265e356d7bcdceb72b8cbb4396ebaeba32a103b43508888860405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a16002600182815481101515611c9157fe5b90600052602060002090600b020160020154811515611cac57fe5b04600182815481101515611cbc57fe5b90600052602060002090600b0201600301541115611dfa576020604051908101604052806000815250600182815481101515611cf457fe5b90600052602060002090600b02016004016000019080519060200190611d1b92919061263e565b506020604051908101604052806000815250600182815481101515611d3c57fe5b90600052602060002090600b02016004016001019080519060200190611d6392919061263e565b506000600182815481101515611d7557fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600182815481101515611dd857fe5b90600052602060002090600b0201600401600301819055506001935050611e00565b60009350505b5050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630e32cf906040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611e8d57600080fd5b505afa158015611ea1573d6000803e3d6000fd5b505050506040513d6020811015611eb757600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f696e76616c69642063616c6c657200000000000000000000000000000000000081525060200191505060405180910390fd5b611fb988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000612554565b1515612010576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806128546034913960400191505060405180910390fd5b600061205f89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612353565b9050868660018381548110151561207257fe5b90600052602060002090600b020160040160000191906120939291906125be565b5084846001838154811015156120a557fe5b90600052602060002090600b020160040160010191906120c69291906125be565b50826001828154811015156120d757fe5b90600052602060002090600b020160040160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160018281548110151561213957fe5b90600052602060002090600b02016004016003018190555060008090505b60018281548110151561216657fe5b90600052602060002090600b0201600801805490508110156122be5760018281548110151561219157fe5b90600052602060002090600b0201600801818154811015156121af57fe5b9060005260206000200160000160149054906101000a900460ff16156122b15760006001838154811015156121e057fe5b90600052602060002090600b0201600a016000848152602001908152602001600020600060018581548110151561221357fe5b90600052602060002090600b02016008018481548110151561223157fe5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b8080600101915050612157565b5060006001828154811015156122d057fe5b90600052602060002090600b0201600301819055507f5bfaebb5931145594f63236d2a59314c4dc6035b65d0ca4cee9c7298e2f06ca3898960405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a1505050505050505050565b6000600160026000846040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561239f578082015181840152602081019050612384565b50505050905090810190601f1680156123cc5780820380516001836020036101000a031916815260200191505b509250505060405160208183030381529060405280519060200120815260200190815260200160002054039050919050565b60008061240a84612353565b90506001808281548110151561241c57fe5b90600052602060002090600b020160090160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540391505092915050565b60008061248184612353565b9050600060018281548110151561249457fe5b90600052602060002090600b020160090160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156124f357600091505061254e565b60006124ff85856123fe565b905060018281548110151561251057fe5b90600052602060002090600b02016008018181548110151561252e57fe5b9060005260206000200160000160149054906101000a900460ff16925050505b92915050565b600081600161256285612353565b81548110151561256e57fe5b90600052602060002090600b02016004016003015414905092915050565b8154818355818111156125b957600b0281600b0283600052602060002091820191016125b891906126be565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106125ff57803560ff191683800117855561262d565b8280016001018555821561262d579182015b8281111561262c578235825591602001919060010190612611565b5b50905061263a919061276b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061267f57805160ff19168380011785556126ad565b828001600101855582156126ad579182015b828111156126ac578251825591602001919060010190612691565b5b5090506126ba919061276b565b5090565b61276891905b8082111561276457600080820160006126dd9190612790565b600182016000905560028201600090556003820160009055600482016000808201600061270a9190612790565b60018201600061271a9190612790565b6002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160009055505060088201600061275b91906127d8565b50600b016126c4565b5090565b90565b61278d91905b80821115612789576000816000905550600101612771565b5090565b90565b50805460018160011615610100020316600290046000825580601f106127b657506127d5565b601f0160209004906000526020600020908101906127d4919061276b565b5b50565b50805460008255906000526020600020908101906127f691906127f9565b50565b61285091905b8082111561284c57600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff0219169055506001016127ff565b5090565b9056fe6974656d732070656e64696e6720666f7220617070726f76616c2e206e6577206974656d2063616e6e6f74206265206164646564a165627a7a723058209bcb200dffe1c7dbbf4661d7181f768f85d4dda30f18c49d34e48846e15a15430029 \ No newline at end of file diff --git a/permission/contract/gen/gen.go b/permission/contract/gen/gen.go new file mode 100644 index 0000000000..f499c527c3 --- /dev/null +++ b/permission/contract/gen/gen.go @@ -0,0 +1,27 @@ +// Quorum +// +// this is to generate go binding for smart contracts used in permissioning +// +// Require: +// 1. solc 0.5.4 +// 2. abigen (make all from root) + +//go:generate solc --abi --bin -o . --overwrite ../AccountManager.sol +//go:generate solc --abi --bin -o . --overwrite ../NodeManager.sol +//go:generate solc --abi --bin -o . --overwrite ../OrgManager.sol +//go:generate solc --abi --bin -o . --overwrite ../PermissionsImplementation.sol +//go:generate solc --abi --bin -o . --overwrite ../PermissionsInterface.sol +//go:generate solc --abi --bin -o . --overwrite ../PermissionsUpgradable.sol +//go:generate solc --abi --bin -o . --overwrite ../RoleManager.sol +//go:generate solc --abi --bin -o . --overwrite ../VoterManager.sol + +//go:generate abigen -pkg permission -abi ./AccountManager.abi -bin ./AccountManager.bin -type AcctManager -out ../../bind/accounts.go +//go:generate abigen -pkg permission -abi ./NodeManager.abi -bin ./NodeManager.bin -type NodeManager -out ../../bind/nodes.go +//go:generate abigen -pkg permission -abi ./OrgManager.abi -bin ./OrgManager.bin -type OrgManager -out ../../bind/org.go +//go:generate abigen -pkg permission -abi ./PermissionsImplementation.abi -bin ./PermissionsImplementation.bin -type PermImpl -out ../../bind/permission_impl.go +//go:generate abigen -pkg permission -abi ./PermissionsInterface.abi -bin ./PermissionsInterface.bin -type PermInterface -out ../../bind/permission_interface.go +//go:generate abigen -pkg permission -abi ./PermissionsUpgradable.abi -bin ./PermissionsUpgradable.bin -type PermUpgr -out ../../bind/permission_upgr.go +//go:generate abigen -pkg permission -abi ./RoleManager.abi -bin ./RoleManager.bin -type RoleManager -out ../../bind/roles.go +//go:generate abigen -pkg permission -abi ./VoterManager.abi -bin ./VoterManager.bin -type VoterManager -out ../../bind/voter.go + +package gen diff --git a/permission/permission.go b/permission/permission.go new file mode 100644 index 0000000000..5718ef87d6 --- /dev/null +++ b/permission/permission.go @@ -0,0 +1,857 @@ +package permission + +import ( + "crypto/ecdsa" + "encoding/json" + "fmt" + "github.com/ethereum/go-ethereum/core" + "io/ioutil" + "math/big" + "os" + "path/filepath" + "reflect" + "sync" + "time" + + "github.com/ethereum/go-ethereum/ethclient" + + "github.com/ethereum/go-ethereum/event" + + "github.com/ethereum/go-ethereum/raft" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" + pbind "github.com/ethereum/go-ethereum/permission/bind" +) + +type NodeOperation uint8 + +const ( + NodeAdd NodeOperation = iota + NodeDelete +) + +type PermissionCtrl struct { + node *node.Node + ethClnt bind.ContractBackend + eth *eth.Ethereum + key *ecdsa.PrivateKey + dataDir string + permUpgr *pbind.PermUpgr + permInterf *pbind.PermInterface + permNode *pbind.NodeManager + permAcct *pbind.AcctManager + permRole *pbind.RoleManager + permOrg *pbind.OrgManager + permConfig *types.PermissionConfig + + startWaitGroup *sync.WaitGroup // waitgroup to make sure all dependenies are ready before we start the service + stopFeed event.Feed // broadcasting stopEvent when service is being stopped + errorChan chan error // channel to capture error when starting aysnc + + mux sync.Mutex +} + +// to signal all watches when service is stopped +type stopEvent struct { +} + +// function reads the permissions config file passed and populates the +// config structure accordingly +func ParsePermissionConfig(dir string) (types.PermissionConfig, error) { + fullPath := filepath.Join(dir, params.PERMISSION_MODEL_CONFIG) + f, err := os.Open(fullPath) + if err != nil { + log.Error("can't open file", "file", fullPath, "error", err) + return types.PermissionConfig{}, err + } + defer func() { + _ = f.Close() + }() + + var permConfig types.PermissionConfig + blob, err := ioutil.ReadFile(fullPath) + if err != nil { + log.Error("error reading file", "err", err, "file", fullPath) + } + + err = json.Unmarshal(blob, &permConfig) + if err != nil { + log.Error("error unmarshalling the file", "err", err, "file", fullPath) + } + + if len(permConfig.Accounts) == 0 { + return types.PermissionConfig{}, fmt.Errorf("no accounts given in %s. Network cannot boot up", params.PERMISSION_MODEL_CONFIG) + } + if permConfig.SubOrgDepth.Cmp(big.NewInt(0)) == 0 || permConfig.SubOrgBreadth.Cmp(big.NewInt(0)) == 0 { + return types.PermissionConfig{}, fmt.Errorf("sub org breadth depth not passed in %s. Network cannot boot up", params.PERMISSION_MODEL_CONFIG) + } + if permConfig.IsEmpty() { + return types.PermissionConfig{}, fmt.Errorf("missing contract addresses in %s", params.PERMISSION_MODEL_CONFIG) + } + + return permConfig, nil +} + +// Create a service instance for permissioning +// +// Permission Service depends on the following: +// 1. EthService to be ready +// 2. Downloader to sync up blocks +// 3. InProc RPC server to be ready +func NewQuorumPermissionCtrl(stack *node.Node, pconfig *types.PermissionConfig) (*PermissionCtrl, error) { + wg := &sync.WaitGroup{} + wg.Add(1) + p := &PermissionCtrl{ + node: stack, + key: stack.GetNodeKey(), + dataDir: stack.DataDir(), + permConfig: pconfig, + startWaitGroup: wg, + errorChan: make(chan error), + } + + stopChan, stopSubscription := p.subscribeStopEvent() + inProcRPCServerSub := stack.EventMux().Subscribe(rpc.InProcServerReadyEvent{}) + log.Debug("permission service: waiting for InProcRPC Server") + + go func(_wg *sync.WaitGroup) { + defer func(start time.Time) { + log.Debug("permission service: InProcRPC server is ready", "took", time.Since(start)) + stopSubscription.Unsubscribe() + inProcRPCServerSub.Unsubscribe() + _wg.Done() + }(time.Now()) + select { + case <-inProcRPCServerSub.Chan(): + case <-stopChan: + } + }(wg) // wait for inproc RPC to be ready + return p, nil +} + +func (p *PermissionCtrl) bindContract(contractInstance interface{}, bindFunc func() (interface{}, error)) error { + element := reflect.ValueOf(contractInstance).Elem() + instance, err := bindFunc() + if err != nil { + return err + } + element.Set(reflect.ValueOf(instance)) + return nil +} + +// This is to make sure all contract instances are ready and initialized +// +// Required to be call after standard service start lifecycle +func (p *PermissionCtrl) AfterStart() error { + log.Debug("permission service: binding contracts") + err := <-p.errorChan // capture any error happened during asyncStart. Also wait here if asyncStart is not yet finish + if err != nil { + return err + } + if err := p.bindContract(&p.permUpgr, func() (interface{}, error) { return pbind.NewPermUpgr(p.permConfig.UpgrdAddress, p.ethClnt) }); err != nil { + return err + } + if err := p.bindContract(&p.permInterf, func() (interface{}, error) { return pbind.NewPermInterface(p.permConfig.InterfAddress, p.ethClnt) }); err != nil { + return err + } + if err := p.bindContract(&p.permAcct, func() (interface{}, error) { return pbind.NewAcctManager(p.permConfig.AccountAddress, p.ethClnt) }); err != nil { + return err + } + if err := p.bindContract(&p.permNode, func() (interface{}, error) { return pbind.NewNodeManager(p.permConfig.NodeAddress, p.ethClnt) }); err != nil { + return err + } + if err := p.bindContract(&p.permRole, func() (interface{}, error) { return pbind.NewRoleManager(p.permConfig.RoleAddress, p.ethClnt) }); err != nil { + return err + } + if err := p.bindContract(&p.permOrg, func() (interface{}, error) { return pbind.NewOrgManager(p.permConfig.OrgAddress, p.ethClnt) }); err != nil { + return err + } + + // populate the initial list of permissioned nodes and account accesses + if err := p.populateInitPermissions(); err != nil { + return fmt.Errorf("populateInitPermissions failed: %v", err) + } + + // set the default access to ReadOnly + types.SetDefaults(p.permConfig.NwAdminRole, p.permConfig.OrgAdminRole) + + for _, f := range []func() error{ + p.monitorQIP714Block, // monitor block number to activate new permissions controls + p.manageOrgPermissions, // monitor org management related events + p.manageNodePermissions, // monitor org level node management events + p.manageRolePermissions, // monitor org level role management events + p.manageAccountPermissions, // monitor org level account management events + } { + if err := f(); err != nil { + return err + } + } + + log.Info("permission service: is now ready") + + return nil +} + +// start service asynchronously due to dependencies +func (p *PermissionCtrl) asyncStart() { + var ethereum *eth.Ethereum + // will be blocked here until node is up + if err := p.node.Service(ðereum); err != nil { + p.errorChan <- fmt.Errorf("dependent ethereum service not started") + return + } + defer func() { + p.errorChan <- nil + }() + // for cases where the node is joining an existing network, permission service + // can be brought up only after block syncing is complete. This function + // waits for block syncing before the starting permissions + p.startWaitGroup.Add(1) + go func(_wg *sync.WaitGroup) { + log.Debug("permission service: waiting for downloader") + stopChan, stopSubscription := p.subscribeStopEvent() + pollingTicker := time.NewTicker(10 * time.Millisecond) + defer func(start time.Time) { + log.Debug("permission service: downloader completed", "took", time.Since(start)) + stopSubscription.Unsubscribe() + pollingTicker.Stop() + _wg.Done() + }(time.Now()) + for { + select { + case <-pollingTicker.C: + if types.GetSyncStatus() && !ethereum.Downloader().Synchronising() { + return + } + case <-stopChan: + return + } + } + }(p.startWaitGroup) // wait for downloader to sync if any + + log.Debug("permission service: waiting for all dependencies to be ready") + p.startWaitGroup.Wait() + client, err := p.node.Attach() + if err != nil { + p.errorChan <- fmt.Errorf("unable to create rpc client: %v", err) + return + } + p.ethClnt = ethclient.NewClient(client) + p.eth = ethereum +} + +func (p *PermissionCtrl) Start(srvr *p2p.Server) error { + log.Debug("permission service: starting") + go func() { + log.Debug("permission service: starting async") + p.asyncStart() + }() + return nil +} + +func (p *PermissionCtrl) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: "quorumPermission", + Version: "1.0", + Service: NewQuorumControlsAPI(p), + Public: true, + }, + } +} + +func (p *PermissionCtrl) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +func (p *PermissionCtrl) Stop() error { + log.Info("permission service: stopping") + p.stopFeed.Send(stopEvent{}) + log.Info("permission service: stopped") + return nil +} + +// monitors QIP714Block and set default access +func (p *PermissionCtrl) monitorQIP714Block() error { + // if QIP714block is not given, set the default access + // to readonly + if p.eth.ChainConfig().QIP714Block == nil { + types.SetDefaultAccess() + return nil + } + //QIP714block is given, monitor block count + go func() { + chainHeadCh := make(chan core.ChainHeadEvent, 1) + headSub := p.eth.BlockChain().SubscribeChainHeadEvent(chainHeadCh) + defer headSub.Unsubscribe() + stopChan, stopSubscription := p.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + for { + select { + case head := <-chainHeadCh: + if p.eth.ChainConfig().IsQIP714(head.Block.Number()) { + types.SetDefaultAccess() + return + } + case <-stopChan: + return + } + } + }() + return nil +} + +// monitors org management related events happening via smart contracts +// and updates cache accordingly +func (p *PermissionCtrl) manageOrgPermissions() error { + chPendingApproval := make(chan *pbind.OrgManagerOrgPendingApproval, 1) + chOrgApproved := make(chan *pbind.OrgManagerOrgApproved, 1) + chOrgSuspended := make(chan *pbind.OrgManagerOrgSuspended, 1) + chOrgReactivated := make(chan *pbind.OrgManagerOrgSuspensionRevoked, 1) + + opts := &bind.WatchOpts{} + var blockNumber uint64 = 1 + opts.Start = &blockNumber + + if _, err := p.permOrg.OrgManagerFilterer.WatchOrgPendingApproval(opts, chPendingApproval); err != nil { + return fmt.Errorf("failed WatchNodePendingApproval: %v", err) + } + + if _, err := p.permOrg.OrgManagerFilterer.WatchOrgApproved(opts, chOrgApproved); err != nil { + return fmt.Errorf("failed WatchNodePendingApproval: %v", err) + } + + if _, err := p.permOrg.OrgManagerFilterer.WatchOrgSuspended(opts, chOrgSuspended); err != nil { + return fmt.Errorf("failed WatchNodePendingApproval: %v", err) + } + + if _, err := p.permOrg.OrgManagerFilterer.WatchOrgSuspensionRevoked(opts, chOrgReactivated); err != nil { + return fmt.Errorf("failed WatchNodePendingApproval: %v", err) + } + + go func() { + stopChan, stopSubscription := p.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + for { + select { + case evtPendingApproval := <-chPendingApproval: + types.OrgInfoMap.UpsertOrg(evtPendingApproval.OrgId, evtPendingApproval.PorgId, evtPendingApproval.UltParent, evtPendingApproval.Level, types.OrgStatus(evtPendingApproval.Status.Uint64())) + + case evtOrgApproved := <-chOrgApproved: + types.OrgInfoMap.UpsertOrg(evtOrgApproved.OrgId, evtOrgApproved.PorgId, evtOrgApproved.UltParent, evtOrgApproved.Level, types.OrgApproved) + + case evtOrgSuspended := <-chOrgSuspended: + types.OrgInfoMap.UpsertOrg(evtOrgSuspended.OrgId, evtOrgSuspended.PorgId, evtOrgSuspended.UltParent, evtOrgSuspended.Level, types.OrgSuspended) + + case evtOrgReactivated := <-chOrgReactivated: + types.OrgInfoMap.UpsertOrg(evtOrgReactivated.OrgId, evtOrgReactivated.PorgId, evtOrgReactivated.UltParent, evtOrgReactivated.Level, types.OrgApproved) + case <-stopChan: + log.Info("quit org contract watch") + return + } + } + }() + return nil +} + +func (p *PermissionCtrl) subscribeStopEvent() (chan stopEvent, event.Subscription) { + c := make(chan stopEvent) + s := p.stopFeed.Subscribe(c) + return c, s +} + +// Monitors node management events and updates cache accordingly +func (p *PermissionCtrl) manageNodePermissions() error { + chNodeApproved := make(chan *pbind.NodeManagerNodeApproved, 1) + chNodeProposed := make(chan *pbind.NodeManagerNodeProposed, 1) + chNodeDeactivated := make(chan *pbind.NodeManagerNodeDeactivated, 1) + chNodeActivated := make(chan *pbind.NodeManagerNodeActivated, 1) + chNodeBlacklisted := make(chan *pbind.NodeManagerNodeBlacklisted) + chNodeRecoveryInit := make(chan *pbind.NodeManagerNodeRecoveryInitiated, 1) + chNodeRecoveryDone := make(chan *pbind.NodeManagerNodeRecoveryCompleted, 1) + + opts := &bind.WatchOpts{} + var blockNumber uint64 = 1 + opts.Start = &blockNumber + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeApproved(opts, chNodeApproved); err != nil { + return fmt.Errorf("failed WatchNodeApproved: %v", err) + } + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeProposed(opts, chNodeProposed); err != nil { + return fmt.Errorf("failed WatchNodeProposed: %v", err) + } + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeDeactivated(opts, chNodeDeactivated); err != nil { + return fmt.Errorf("failed NodeDeactivated: %v", err) + } + if _, err := p.permNode.NodeManagerFilterer.WatchNodeActivated(opts, chNodeActivated); err != nil { + return fmt.Errorf("failed WatchNodeActivated: %v", err) + } + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeBlacklisted(opts, chNodeBlacklisted); err != nil { + return fmt.Errorf("failed NodeBlacklisting: %v", err) + } + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryInitiated(opts, chNodeRecoveryInit); err != nil { + return fmt.Errorf("failed NodeRecoveryInitiated: %v", err) + } + + if _, err := p.permNode.NodeManagerFilterer.WatchNodeRecoveryCompleted(opts, chNodeRecoveryDone); err != nil { + return fmt.Errorf("failed NodeRecoveryCompleted: %v", err) + } + + go func() { + stopChan, stopSubscription := p.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + for { + select { + case evtNodeApproved := <-chNodeApproved: + p.updatePermissionedNodes(evtNodeApproved.EnodeId, NodeAdd) + types.NodeInfoMap.UpsertNode(evtNodeApproved.OrgId, evtNodeApproved.EnodeId, types.NodeApproved) + + case evtNodeProposed := <-chNodeProposed: + types.NodeInfoMap.UpsertNode(evtNodeProposed.OrgId, evtNodeProposed.EnodeId, types.NodePendingApproval) + + case evtNodeDeactivated := <-chNodeDeactivated: + p.updatePermissionedNodes(evtNodeDeactivated.EnodeId, NodeDelete) + types.NodeInfoMap.UpsertNode(evtNodeDeactivated.OrgId, evtNodeDeactivated.EnodeId, types.NodeDeactivated) + + case evtNodeActivated := <-chNodeActivated: + p.updatePermissionedNodes(evtNodeActivated.EnodeId, NodeAdd) + types.NodeInfoMap.UpsertNode(evtNodeActivated.OrgId, evtNodeActivated.EnodeId, types.NodeApproved) + + case evtNodeBlacklisted := <-chNodeBlacklisted: + types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed) + p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId, NodeAdd) + p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete) + + case evtNodeRecoveryInit := <-chNodeRecoveryInit: + types.NodeInfoMap.UpsertNode(evtNodeRecoveryInit.OrgId, evtNodeRecoveryInit.EnodeId, types.NodeRecoveryInitiated) + + case evtNodeRecoveryDone := <-chNodeRecoveryDone: + types.NodeInfoMap.UpsertNode(evtNodeRecoveryDone.OrgId, evtNodeRecoveryDone.EnodeId, types.NodeApproved) + p.updateDisallowedNodes(evtNodeRecoveryDone.EnodeId, NodeDelete) + p.updatePermissionedNodes(evtNodeRecoveryDone.EnodeId, NodeAdd) + + case <-stopChan: + log.Info("quit node contract watch") + return + } + } + }() + return nil +} + +// adds or deletes and entry from a given file +func (p *PermissionCtrl) updateFile(fileName, enodeId string, operation NodeOperation, createFile bool) { + // Load the nodes from the config file + var nodeList []string + index := 0 + // if createFile is false means the file is already existing. read the file + if !createFile { + blob, err := ioutil.ReadFile(fileName) + if err != nil && !createFile { + log.Error("Failed to access the file", "fileName", fileName, "err", err) + return + } + + if err := json.Unmarshal(blob, &nodeList); err != nil { + log.Error("Failed to load nodes list from file", "fileName", fileName, "err", err) + return + } + + // logic to update the permissioned-nodes.json file based on action + + recExists := false + for i, eid := range nodeList { + if eid == enodeId { + index = i + recExists = true + break + } + } + if (operation == NodeAdd && recExists) || (operation == NodeDelete && !recExists) { + return + } + } + if operation == NodeAdd { + nodeList = append(nodeList, enodeId) + } else { + nodeList = append(nodeList[:index], nodeList[index+1:]...) + } + blob, _ := json.Marshal(nodeList) + + p.mux.Lock() + defer p.mux.Unlock() + + if err := ioutil.WriteFile(fileName, blob, 0644); err != nil { + log.Error("Error writing new node info to file", "fileName", fileName, "err", err) + } +} + +// updates node information in the permissioned-nodes.json file based on node +// management activities in smart contract +func (p *PermissionCtrl) updatePermissionedNodes(enodeId string, operation NodeOperation) { + log.Debug("updatePermissionedNodes", "DataDir", p.dataDir, "file", params.PERMISSIONED_CONFIG) + + path := filepath.Join(p.dataDir, params.PERMISSIONED_CONFIG) + if _, err := os.Stat(path); err != nil { + log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present", "err", err) + return + } + + p.updateFile(path, enodeId, operation, false) + if operation == NodeDelete { + p.disconnectNode(enodeId) + } +} + +//this function populates the black listed node information into the disallowed-nodes.json file +func (p *PermissionCtrl) updateDisallowedNodes(url string, operation NodeOperation) { + log.Debug("updateDisallowedNodes", "DataDir", p.dataDir, "file", params.BLACKLIST_CONFIG) + + fileExists := true + path := filepath.Join(p.dataDir, params.BLACKLIST_CONFIG) + // Check if the file is existing. If the file is not existing create the file + if _, err := os.Stat(path); err != nil { + log.Error("Read Error for disallowed-nodes.json file", "err", err) + if _, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644); err != nil { + log.Error("Failed to create disallowed-nodes.json file", "err", err) + return + } + fileExists = false + } + + if fileExists { + p.updateFile(path, url, operation, false) + } else { + p.updateFile(path, url, operation, true) + } +} + +// Monitors account access related events and updates the cache accordingly +func (p *PermissionCtrl) manageAccountPermissions() error { + chAccessModified := make(chan *pbind.AcctManagerAccountAccessModified) + chAccessRevoked := make(chan *pbind.AcctManagerAccountAccessRevoked) + chStatusChanged := make(chan *pbind.AcctManagerAccountStatusChanged) + + opts := &bind.WatchOpts{} + var blockNumber uint64 = 1 + opts.Start = &blockNumber + + if _, err := p.permAcct.AcctManagerFilterer.WatchAccountAccessModified(opts, chAccessModified); err != nil { + return fmt.Errorf("failed AccountAccessModified: %v", err) + } + + if _, err := p.permAcct.AcctManagerFilterer.WatchAccountAccessRevoked(opts, chAccessRevoked); err != nil { + return fmt.Errorf("failed AccountAccessRevoked: %v", err) + } + + if _, err := p.permAcct.AcctManagerFilterer.WatchAccountStatusChanged(opts, chStatusChanged); err != nil { + return fmt.Errorf("failed AccountStatusChanged: %v", err) + } + + go func() { + stopChan, stopSubscription := p.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + for { + select { + case evtAccessModified := <-chAccessModified: + types.AcctInfoMap.UpsertAccount(evtAccessModified.OrgId, evtAccessModified.RoleId, evtAccessModified.Account, evtAccessModified.OrgAdmin, types.AcctStatus(int(evtAccessModified.Status.Uint64()))) + + case evtAccessRevoked := <-chAccessRevoked: + types.AcctInfoMap.UpsertAccount(evtAccessRevoked.OrgId, evtAccessRevoked.RoleId, evtAccessRevoked.Account, evtAccessRevoked.OrgAdmin, types.AcctActive) + + case evtStatusChanged := <-chStatusChanged: + ac := types.AcctInfoMap.GetAccount(evtStatusChanged.Account) + types.AcctInfoMap.UpsertAccount(evtStatusChanged.OrgId, ac.RoleId, evtStatusChanged.Account, ac.IsOrgAdmin, types.AcctStatus(int(evtStatusChanged.Status.Uint64()))) + case <-stopChan: + log.Info("quit account contract watch") + return + } + } + }() + return nil +} + +// Disconnect the node from the network +func (p *PermissionCtrl) disconnectNode(enodeId string) { + if p.eth.ChainConfig().Istanbul == nil && p.eth.ChainConfig().Clique == nil { + var raftService *raft.RaftService + if err := p.node.Service(&raftService); err == nil { + raftApi := raft.NewPublicRaftAPI(raftService) + + //get the raftId for the given enodeId + raftId, err := raftApi.GetRaftId(enodeId) + if err == nil { + raftApi.RemovePeer(raftId) + } else { + log.Error("failed to get raft id", "err", err, "enodeId", enodeId) + } + } + } else { + // Istanbul or clique - disconnect the peer + server := p.node.Server() + if server != nil { + node, err := enode.ParseV4(enodeId) + if err == nil { + server.RemovePeer(node) + } else { + log.Error("failed parse node id", "err", err, "enodeId", enodeId) + } + } + } + +} + +// Thus function checks if the initial network boot up status and if no +// populates permissions model with details from permission-config.json +func (p *PermissionCtrl) populateInitPermissions() error { + auth := bind.NewKeyedTransactor(p.key) + permInterfSession := &pbind.PermInterfaceSession{ + Contract: p.permInterf, + CallOpts: bind.CallOpts{ + Pending: true, + }, + TransactOpts: bind.TransactOpts{ + From: auth.From, + Signer: auth.Signer, + GasLimit: 47000000, + GasPrice: big.NewInt(0), + }, + } + + networkInitialized, err := permInterfSession.GetNetworkBootStatus() + if err != nil { + // handle the scenario of no contract code. + log.Warn("Failed to retrieve network boot status ", "err", err) + return err + } + + if !networkInitialized { + if err := p.bootupNetwork(permInterfSession); err != nil { + return err + } + } else { + //populate orgs, nodes, roles and accounts from contract + for _, f := range []func(auth *bind.TransactOpts) error{ + p.populateOrgsFromContract, + p.populateNodesFromContract, + p.populateRolesFromContract, + p.populateAccountsFromContract, + } { + if err := f(auth); err != nil { + return err + } + } + } + + return nil +} + +// initialize the permissions model and populate initial values +func (p *PermissionCtrl) bootupNetwork(permInterfSession *pbind.PermInterfaceSession) error { + if _, err := permInterfSession.SetPolicy(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, p.permConfig.OrgAdminRole); err != nil { + log.Error("bootupNetwork SetPolicy failed", "err", err) + return err + } + if _, err := permInterfSession.Init(p.permConfig.SubOrgBreadth, p.permConfig.SubOrgDepth); err != nil { + log.Error("bootupNetwork init failed", "err", err) + return err + } + + types.OrgInfoMap.UpsertOrg(p.permConfig.NwAdminOrg, "", p.permConfig.NwAdminOrg, big.NewInt(1), types.OrgApproved) + types.RoleInfoMap.UpsertRole(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, true, true, types.FullAccess, true) + // populate the initial node list from static-nodes.json + if err := p.populateStaticNodesToContract(permInterfSession); err != nil { + return err + } + // populate initial account access to full access + if err := p.populateInitAccountAccess(permInterfSession); err != nil { + return err + } + + // update network status to boot completed + if err := p.updateNetworkStatus(permInterfSession); err != nil { + log.Error("failed to updated network boot status", "error", err) + return err + } + return nil +} + +// populates the account access details from contract into cache +func (p *PermissionCtrl) populateAccountsFromContract(auth *bind.TransactOpts) error { + //populate accounts + permAcctSession := &pbind.AcctManagerSession{ + Contract: p.permAcct, + CallOpts: bind.CallOpts{ + Pending: true, + }, + } + + if numberOfRoles, err := permAcctSession.GetNumberOfAccounts(); err == nil { + iOrgNum := numberOfRoles.Uint64() + for k := uint64(0); k < iOrgNum; k++ { + if addr, org, role, status, orgAdmin, err := permAcctSession.GetAccountDetailsFromIndex(big.NewInt(int64(k))); err == nil { + types.AcctInfoMap.UpsertAccount(org, role, addr, orgAdmin, types.AcctStatus(int(status.Int64()))) + } + } + } else { + return err + } + return nil +} + +// populates the role details from contract into cache +func (p *PermissionCtrl) populateRolesFromContract(auth *bind.TransactOpts) error { + //populate roles + permRoleSession := &pbind.RoleManagerSession{ + Contract: p.permRole, + CallOpts: bind.CallOpts{ + Pending: true, + }, + } + if numberOfRoles, err := permRoleSession.GetNumberOfRoles(); err == nil { + iOrgNum := numberOfRoles.Uint64() + for k := uint64(0); k < iOrgNum; k++ { + if roleStruct, err := permRoleSession.GetRoleDetailsFromIndex(big.NewInt(int64(k))); err == nil { + types.RoleInfoMap.UpsertRole(roleStruct.OrgId, roleStruct.RoleId, roleStruct.Voter, roleStruct.Admin, types.AccessType(int(roleStruct.AccessType.Int64())), roleStruct.Active) + } + } + + } else { + return err + } + return nil +} + +// populates the node details from contract into cache +func (p *PermissionCtrl) populateNodesFromContract(auth *bind.TransactOpts) error { + //populate nodes + permNodeSession := &pbind.NodeManagerSession{ + Contract: p.permNode, + CallOpts: bind.CallOpts{ + Pending: true, + }, + } + if numberOfNodes, err := permNodeSession.GetNumberOfNodes(); err == nil { + iOrgNum := numberOfNodes.Uint64() + for k := uint64(0); k < iOrgNum; k++ { + if nodeStruct, err := permNodeSession.GetNodeDetailsFromIndex(big.NewInt(int64(k))); err == nil { + types.NodeInfoMap.UpsertNode(nodeStruct.OrgId, nodeStruct.EnodeId, types.NodeStatus(int(nodeStruct.NodeStatus.Int64()))) + } + } + } else { + return err + } + return nil +} + +// populates the org details from contract into cache +func (p *PermissionCtrl) populateOrgsFromContract(auth *bind.TransactOpts) error { + //populate orgs + permOrgSession := &pbind.OrgManagerSession{ + Contract: p.permOrg, + CallOpts: bind.CallOpts{ + Pending: true, + }, + } + if numberOfOrgs, err := permOrgSession.GetNumberOfOrgs(); err == nil { + iOrgNum := numberOfOrgs.Uint64() + for k := uint64(0); k < iOrgNum; k++ { + if orgId, porgId, ultParent, level, status, err := permOrgSession.GetOrgInfo(big.NewInt(int64(k))); err == nil { + types.OrgInfoMap.UpsertOrg(orgId, porgId, ultParent, level, types.OrgStatus(int(status.Int64()))) + } + } + } else { + return err + } + return nil +} + +// Reads the node list from static-nodes.json and populates into the contract +func (p *PermissionCtrl) populateStaticNodesToContract(permissionsSession *pbind.PermInterfaceSession) error { + nodes := p.node.Server().Config.StaticNodes + for _, node := range nodes { + _, err := permissionsSession.AddAdminNode(node.String()) + if err != nil { + log.Warn("Failed to propose node", "err", err, "enode", node.EnodeID()) + return err + } + types.NodeInfoMap.UpsertNode(p.permConfig.NwAdminOrg, node.String(), 2) + } + return nil +} + +// Invokes the initAccounts function of smart contract to set the initial +// set of accounts access to full access +func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.PermInterfaceSession) error { + for _, a := range p.permConfig.Accounts { + _, er := permissionsSession.AddAdminAccount(a) + if er != nil { + log.Warn("Error adding permission initial account list", "err", er, "account", a) + return er + } + types.AcctInfoMap.UpsertAccount(p.permConfig.NwAdminOrg, p.permConfig.NwAdminRole, a, true, 2) + } + return nil +} + +// updates network boot status to true +func (p *PermissionCtrl) updateNetworkStatus(permissionsSession *pbind.PermInterfaceSession) error { + _, err := permissionsSession.UpdateNetworkBootStatus() + if err != nil { + log.Warn("Failed to udpate network boot status ", "err", err) + return err + } + return nil +} + +// monitors role management related events and updated cache +func (p *PermissionCtrl) manageRolePermissions() error { + chRoleCreated := make(chan *pbind.RoleManagerRoleCreated, 1) + chRoleRevoked := make(chan *pbind.RoleManagerRoleRevoked, 1) + + opts := &bind.WatchOpts{} + var blockNumber uint64 = 1 + opts.Start = &blockNumber + + if _, err := p.permRole.RoleManagerFilterer.WatchRoleCreated(opts, chRoleCreated); err != nil { + return fmt.Errorf("failed WatchRoleCreated: %v", err) + } + + if _, err := p.permRole.RoleManagerFilterer.WatchRoleRevoked(opts, chRoleRevoked); err != nil { + return fmt.Errorf("failed WatchRoleRemoved: %v", err) + } + + go func() { + stopChan, stopSubscription := p.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + for { + select { + case evtRoleCreated := <-chRoleCreated: + types.RoleInfoMap.UpsertRole(evtRoleCreated.OrgId, evtRoleCreated.RoleId, evtRoleCreated.IsVoter, evtRoleCreated.IsAdmin, types.AccessType(int(evtRoleCreated.BaseAccess.Uint64())), true) + + case evtRoleRevoked := <-chRoleRevoked: + if r := types.RoleInfoMap.GetRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId); r != nil { + types.RoleInfoMap.UpsertRole(evtRoleRevoked.OrgId, evtRoleRevoked.RoleId, r.IsVoter, r.IsAdmin, r.Access, false) + } else { + log.Error("Revoke role - cache is missing role", "org", evtRoleRevoked.OrgId, "role", evtRoleRevoked.RoleId) + } + case <-stopChan: + log.Info("quit role contract watch") + return + } + } + }() + return nil +} diff --git a/permission/permission_test.go b/permission/permission_test.go new file mode 100644 index 0000000000..044bd8b13a --- /dev/null +++ b/permission/permission_test.go @@ -0,0 +1,623 @@ +package permission + +import ( + "crypto/ecdsa" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "log" + "math/big" + "os" + "testing" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/internal/ethapi" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum/go-ethereum/p2p" + + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/eth" + + "github.com/stretchr/testify/assert" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/node" + pbind "github.com/ethereum/go-ethereum/permission/bind" +) + +const ( + arbitraryNetworkAdminOrg = "NETWORK_ADMIN" + arbitraryNetworkAdminRole = "NETWORK_ADMIN_ROLE" + arbitraryOrgAdminRole = "ORG_ADMIN_ROLE" + arbitraryNode1 = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@127.0.0.1:21000?discport=0&raftport=50401" + arbitraryNode2 = "enode://0ba6b9f606a43a95edc6247cdb1c1e105145817be7bcafd6b2c0ba15d58145f0dc1a194f70ba73cd6f4cdd6864edc7687f311254c7555cc32e4d45aeb1b80416@127.0.0.1:21001?discport=0&raftport=50402" + arbitraryOrgToAdd = "ORG1" + arbitrarySubOrg = "SUB1" + arbitrartNewRole1 = "NEW_ROLE_1" + arbitrartNewRole2 = "NEW_ROLE_2" +) + +var ErrAccountsLinked = errors.New("Accounts linked to the role. Cannot be removed") +var ErrPendingApproval = errors.New("Pending approvals for the organization. Approve first") +var ErrAcctBlacklisted = errors.New("Blacklisted account. Operation not allowed") +var ErrNodeBlacklisted = errors.New("Blacklisted node. Operation not allowed") + +var ( + guardianKey *ecdsa.PrivateKey + guardianAccount accounts.Account + backend bind.ContractBackend + permUpgrAddress, permInterfaceAddress, permImplAddress, voterManagerAddress, + nodeManagerAddress, roleManagerAddress, accountManagerAddress, orgManagerAddress common.Address + ethereum *eth.Ethereum + stack *node.Node + guardianAddress common.Address +) + +func TestMain(m *testing.M) { + setup() + ret := m.Run() + teardown() + os.Exit(ret) +} + +func setup() { + var err error + t := log.New(os.Stdout, "", 0) + + ksdir, _, err := tmpKeyStore(false) + defer os.RemoveAll(ksdir) + + if err != nil { + t.Fatalf("failed to create keystore: %v\n", err) + } + nodeKey, _ := crypto.GenerateKey() + guardianKey, _ = crypto.GenerateKey() + + // Create a network-less protocol stack and start an Ethereum service within + stack, err = node.New(&node.Config{ + DataDir: "", + KeyStoreDir: ksdir, + UseLightweightKDF: true, + P2P: p2p.Config{ + PrivateKey: nodeKey, + }, + }) + + ksbackend := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + guardianAccount, err = ksbackend.ImportECDSA(guardianKey, "foo") + guardianAddress = guardianAccount.Address + if err != nil { + t.Fatal(err) + } + err = ksbackend.TimedUnlock(guardianAccount, "foo", 0) + if err != nil { + t.Fatal("failed to unlock") + } + + genesisAlloc := map[common.Address]core.GenesisAccount{ + guardianAddress: { + Balance: big.NewInt(100000000000000), + }, + } + ethConf := ð.Config{ + Genesis: &core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: 10000000000, Alloc: genesisAlloc}, + Etherbase: guardianAddress, + Ethash: ethash.Config{ + PowMode: ethash.ModeTest, + }, + } + + if err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil { + t.Fatalf("failed to register Ethereum protocol: %v", err) + } + // Start the node and assemble the JavaScript console around it + if err = stack.Start(); err != nil { + t.Fatalf("failed to start test stack: %v", err) + } + if err := stack.Service(ðereum); err != nil { + t.Fatal(err) + } + backend = backends.NewSimulatedBackendFrom(ethereum) + + var permUpgrInstance *pbind.PermUpgr + + guardianTransactor := bind.NewKeyedTransactor(guardianKey) + + permUpgrAddress, _, permUpgrInstance, err = pbind.DeployPermUpgr(guardianTransactor, backend, guardianAddress) + if err != nil { + t.Fatal(err) + } + permInterfaceAddress, _, _, err = pbind.DeployPermInterface(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + nodeManagerAddress, _, _, err = pbind.DeployNodeManager(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + roleManagerAddress, _, _, err = pbind.DeployRoleManager(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + accountManagerAddress, _, _, err = pbind.DeployAcctManager(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + orgManagerAddress, _, _, err = pbind.DeployOrgManager(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + voterManagerAddress, _, _, err = pbind.DeployVoterManager(guardianTransactor, backend, permUpgrAddress) + if err != nil { + t.Fatal(err) + } + permImplAddress, _, _, err = pbind.DeployPermImpl(guardianTransactor, backend, permUpgrAddress, orgManagerAddress, roleManagerAddress, accountManagerAddress, voterManagerAddress, nodeManagerAddress) + if err != nil { + t.Fatal(err) + } + // call init + if _, err := permUpgrInstance.Init(guardianTransactor, permInterfaceAddress, permImplAddress); err != nil { + t.Fatal(err) + } + + fmt.Printf("current block is %v\n", ethereum.BlockChain().CurrentBlock().Number().Int64()) +} + +func teardown() { + +} + +func TestPermissionCtrl_AfterStart(t *testing.T) { + testObject := typicalPermissionCtrl(t) + + err := testObject.AfterStart() + + assert.NoError(t, err) + assert.NotNil(t, testObject.permOrg) + assert.NotNil(t, testObject.permRole) + assert.NotNil(t, testObject.permNode) + assert.NotNil(t, testObject.permAcct) + assert.NotNil(t, testObject.permInterf) + assert.NotNil(t, testObject.permUpgr) + + isNetworkInitialized, err := testObject.permInterf.GetNetworkBootStatus(&bind.CallOpts{ + Pending: true, + }) + assert.NoError(t, err) + assert.True(t, isNetworkInitialized) +} + +func TestPermissionCtrl_PopulateInitPermissions_AfterNetworkIsInitialized(t *testing.T) { + testObject := typicalPermissionCtrl(t) + assert.NoError(t, testObject.AfterStart()) + + err := testObject.populateInitPermissions() + + assert.NoError(t, err) + + // assert cache + assert.Equal(t, 1, len(types.OrgInfoMap.GetOrgList())) + cachedOrg := types.OrgInfoMap.GetOrgList()[0] + assert.Equal(t, arbitraryNetworkAdminOrg, cachedOrg.OrgId) + assert.Equal(t, arbitraryNetworkAdminOrg, cachedOrg.FullOrgId) + assert.Equal(t, arbitraryNetworkAdminOrg, cachedOrg.UltimateParent) + assert.Equal(t, "", cachedOrg.ParentOrgId) + assert.Equal(t, types.OrgApproved, cachedOrg.Status) + assert.Equal(t, 0, len(cachedOrg.SubOrgList)) + assert.Equal(t, big.NewInt(1), cachedOrg.Level) + + assert.Equal(t, 1, len(types.RoleInfoMap.GetRoleList())) + cachedRole := types.RoleInfoMap.GetRoleList()[0] + assert.Equal(t, arbitraryNetworkAdminOrg, cachedRole.OrgId) + assert.Equal(t, arbitraryNetworkAdminRole, cachedRole.RoleId) + assert.True(t, cachedRole.Active) + assert.True(t, cachedRole.IsAdmin) + assert.True(t, cachedRole.IsVoter) + assert.Equal(t, types.FullAccess, cachedRole.Access) + + assert.Equal(t, 0, len(types.NodeInfoMap.GetNodeList())) + + assert.Equal(t, 1, len(types.AcctInfoMap.GetAcctList())) + cachedAccount := types.AcctInfoMap.GetAcctList()[0] + assert.Equal(t, arbitraryNetworkAdminOrg, cachedAccount.OrgId) + assert.Equal(t, arbitraryNetworkAdminRole, cachedAccount.RoleId) + assert.Equal(t, types.AcctActive, cachedAccount.Status) + assert.True(t, cachedAccount.IsOrgAdmin) + assert.Equal(t, guardianAddress, cachedAccount.AcctId) +} + +func typicalQuorumControlsAPI(t *testing.T) *QuorumControlsAPI { + pc := typicalPermissionCtrl(t) + if !assert.NoError(t, pc.AfterStart()) { + t.Fail() + } + if !assert.NoError(t, pc.populateInitPermissions()) { + t.Fail() + } + return NewQuorumControlsAPI(pc) +} + +func TestQuorumControlsAPI_ListAPIs(t *testing.T) { + testObject := typicalQuorumControlsAPI(t) + + orgDetails, err := testObject.GetOrgDetails(arbitraryNetworkAdminOrg) + assert.NoError(t, err) + assert.Equal(t, orgDetails.AcctList[0].AcctId, guardianAddress) + assert.Equal(t, orgDetails.RoleList[0].RoleId, arbitraryNetworkAdminRole) + + orgDetails, err = testObject.GetOrgDetails("XYZ") + assert.Equal(t, err, errors.New("org does not exist")) + + // test NodeList + assert.Equal(t, len(testObject.NodeList()), 0) + // test AcctList + assert.True(t, len(testObject.AcctList()) > 0, fmt.Sprintf("expected non zero account list")) + // test OrgList + assert.True(t, len(testObject.OrgList()) > 0, fmt.Sprintf("expected non zero org list")) + // test RoleList + assert.True(t, len(testObject.RoleList()) > 0, fmt.Sprintf("expected non zero org list")) +} + +func TestQuorumControlsAPI_OrgAPIs(t *testing.T) { + testObject := typicalQuorumControlsAPI(t) + invalidTxa := ethapi.SendTxArgs{From: getArbitraryAccount()} + txa := ethapi.SendTxArgs{From: guardianAddress} + + // test AddOrg + orgAdminKey, _ := crypto.GenerateKey() + orgAdminAddress := crypto.PubkeyToAddress(orgAdminKey.PublicKey) + + _, err := testObject.AddOrg(arbitraryOrgToAdd, arbitraryNode1, orgAdminAddress, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AddOrg(arbitraryOrgToAdd, arbitraryNode1, orgAdminAddress, txa) + assert.NoError(t, err) + + _, err = testObject.AddOrg(arbitraryOrgToAdd, arbitraryNode1, orgAdminAddress, txa) + assert.Equal(t, err, ErrPendingApproval) + + _, err = testObject.ApproveOrg(arbitraryOrgToAdd, arbitraryNode1, orgAdminAddress, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ApproveOrg("XYZ", arbitraryNode1, orgAdminAddress, txa) + assert.Equal(t, err, errors.New("Nothing to approve")) + + _, err = testObject.ApproveOrg(arbitraryOrgToAdd, arbitraryNode1, orgAdminAddress, txa) + assert.NoError(t, err) + + types.OrgInfoMap.UpsertOrg(arbitraryOrgToAdd, "", arbitraryOrgToAdd, big.NewInt(1), types.OrgApproved) + _, err = testObject.UpdateOrgStatus(arbitraryOrgToAdd, uint8(SuspendOrg), invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.UpdateOrgStatus(arbitraryOrgToAdd, uint8(SuspendOrg), txa) + assert.NoError(t, err) + + types.OrgInfoMap.UpsertOrg(arbitraryOrgToAdd, "", arbitraryOrgToAdd, big.NewInt(1), types.OrgSuspended) + _, err = testObject.ApproveOrgStatus(arbitraryOrgToAdd, uint8(SuspendOrg), invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ApproveOrgStatus(arbitraryOrgToAdd, uint8(SuspendOrg), txa) + assert.NoError(t, err) + + _, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, arbitrarySubOrg, "", invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, arbitrarySubOrg, "", txa) + assert.NoError(t, err) + types.OrgInfoMap.UpsertOrg(arbitrarySubOrg, arbitraryNetworkAdminOrg, arbitraryNetworkAdminOrg, big.NewInt(2), types.OrgApproved) + + suborg := "ABC.12345" + _, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, suborg, "", txa) + assert.Equal(t, err, errors.New("Org id cannot contain special characters")) + + _, err = testObject.AddSubOrg(arbitraryNetworkAdminOrg, "", "", txa) + assert.Equal(t, err, errors.New("Invalid input")) + + _, err = testObject.GetOrgDetails(arbitraryOrgToAdd) + assert.NoError(t, err) + +} + +func TestQuorumControlsAPI_NodeAPIs(t *testing.T) { + testObject := typicalQuorumControlsAPI(t) + invalidTxa := ethapi.SendTxArgs{From: getArbitraryAccount()} + txa := ethapi.SendTxArgs{From: guardianAddress} + + _, err := testObject.AddNode(arbitraryNetworkAdminOrg, arbitraryNode2, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AddNode(arbitraryNetworkAdminOrg, arbitraryNode2, txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeApproved) + + _, err = testObject.UpdateNodeStatus(arbitraryNetworkAdminOrg, arbitraryNode2, uint8(SuspendNode), invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.UpdateNodeStatus(arbitraryNetworkAdminOrg, arbitraryNode2, uint8(SuspendNode), txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeDeactivated) + + _, err = testObject.UpdateNodeStatus(arbitraryNetworkAdminOrg, arbitraryNode2, uint8(ActivateSuspendedNode), txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeApproved) + + _, err = testObject.UpdateNodeStatus(arbitraryNetworkAdminOrg, arbitraryNode2, uint8(BlacklistNode), txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeBlackListed) + + _, err = testObject.UpdateNodeStatus(arbitraryNetworkAdminOrg, arbitraryNode2, uint8(ActivateSuspendedNode), txa) + assert.Equal(t, err, ErrNodeBlacklisted) + + _, err = testObject.RecoverBlackListedNode(arbitraryNetworkAdminOrg, arbitraryNode2, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.RecoverBlackListedNode(arbitraryNetworkAdminOrg, arbitraryNode2, txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeRecoveryInitiated) + + _, err = testObject.ApproveBlackListedNodeRecovery(arbitraryNetworkAdminOrg, arbitraryNode2, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ApproveBlackListedNodeRecovery(arbitraryNetworkAdminOrg, arbitraryNode2, txa) + assert.NoError(t, err) + types.NodeInfoMap.UpsertNode(arbitraryNetworkAdminOrg, arbitraryNode2, types.NodeApproved) +} + +func TestQuorumControlsAPI_RoleAndAccountsAPIs(t *testing.T) { + testObject := typicalQuorumControlsAPI(t) + invalidTxa := ethapi.SendTxArgs{From: getArbitraryAccount()} + txa := ethapi.SendTxArgs{From: guardianAddress} + acct := getArbitraryAccount() + + _, err := testObject.AssignAdminRole(arbitraryNetworkAdminOrg, acct, arbitraryNetworkAdminRole, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AssignAdminRole(arbitraryNetworkAdminOrg, acct, arbitraryNetworkAdminRole, txa) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitraryNetworkAdminRole, acct, true, types.AcctPendingApproval) + + _, err = testObject.ApproveAdminRole(arbitraryNetworkAdminOrg, acct, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ApproveAdminRole(arbitraryNetworkAdminOrg, acct, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ApproveAdminRole(arbitraryNetworkAdminOrg, acct, txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitraryNetworkAdminRole, acct, true, types.AcctActive) + + _, err = testObject.AddNewRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, uint8(types.FullAccess), false, false, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AddNewRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, uint8(types.FullAccess), false, false, txa) + assert.NoError(t, err) + types.RoleInfoMap.UpsertRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, false, false, types.FullAccess, true) + + acct = getArbitraryAccount() + _, err = testObject.AddAccountToOrg(acct, arbitraryNetworkAdminOrg, arbitrartNewRole1, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.AddAccountToOrg(acct, arbitraryNetworkAdminOrg, arbitrartNewRole1, txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole1, acct, true, types.AcctActive) + + _, err = testObject.RemoveRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.RemoveRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, txa) + assert.Equal(t, err, ErrAccountsLinked) + + _, err = testObject.AddNewRole(arbitraryNetworkAdminOrg, arbitrartNewRole2, uint8(types.FullAccess), false, false, txa) + assert.NoError(t, err) + types.RoleInfoMap.UpsertRole(arbitraryNetworkAdminOrg, arbitrartNewRole2, false, false, types.FullAccess, true) + + _, err = testObject.ChangeAccountRole(acct, arbitraryNetworkAdminOrg, arbitrartNewRole2, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.ChangeAccountRole(acct, arbitraryNetworkAdminOrg, arbitrartNewRole2, txa) + assert.NoError(t, err) + + _, err = testObject.RemoveRole(arbitraryNetworkAdminOrg, arbitrartNewRole1, txa) + assert.Equal(t, err, ErrAccountsLinked) + + _, err = testObject.UpdateAccountStatus(arbitraryNetworkAdminOrg, acct, uint8(SuspendAccount), invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.UpdateAccountStatus(arbitraryNetworkAdminOrg, acct, uint8(SuspendAccount), txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctSuspended) + + _, err = testObject.UpdateAccountStatus(arbitraryNetworkAdminOrg, acct, uint8(ActivateSuspendedAccount), txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctActive) + + _, err = testObject.UpdateAccountStatus(arbitraryNetworkAdminOrg, acct, uint8(BlacklistAccount), txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctBlacklisted) + + _, err = testObject.UpdateAccountStatus(arbitraryNetworkAdminOrg, acct, uint8(ActivateSuspendedAccount), txa) + assert.Equal(t, err, ErrAcctBlacklisted) + + _, err = testObject.RecoverBlackListedAccount(arbitraryNetworkAdminOrg, acct, invalidTxa) + assert.Equal(t, err, errors.New("Invalid account id")) + + _, err = testObject.RecoverBlackListedAccount(arbitraryNetworkAdminOrg, acct, txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctRecoveryInitiated) + _, err = testObject.ApproveBlackListedAccountRecovery(arbitraryNetworkAdminOrg, acct, txa) + assert.NoError(t, err) + types.AcctInfoMap.UpsertAccount(arbitraryNetworkAdminOrg, arbitrartNewRole2, acct, true, types.AcctActive) + +} + +func getArbitraryAccount() common.Address { + acctKey, _ := crypto.GenerateKey() + return crypto.PubkeyToAddress(acctKey.PublicKey) +} + +func typicalPermissionCtrl(t *testing.T) *PermissionCtrl { + testObject, err := NewQuorumPermissionCtrl(stack, &types.PermissionConfig{ + UpgrdAddress: permUpgrAddress, + InterfAddress: permInterfaceAddress, + ImplAddress: permImplAddress, + NodeAddress: nodeManagerAddress, + AccountAddress: accountManagerAddress, + RoleAddress: roleManagerAddress, + VoterAddress: voterManagerAddress, + OrgAddress: orgManagerAddress, + NwAdminOrg: arbitraryNetworkAdminOrg, + NwAdminRole: arbitraryNetworkAdminRole, + OrgAdminRole: arbitraryOrgAdminRole, + Accounts: []common.Address{ + guardianAddress, + }, + SubOrgDepth: big.NewInt(3), + SubOrgBreadth: big.NewInt(3), + }) + if err != nil { + t.Fatal(err) + } + testObject.ethClnt = backend + testObject.eth = ethereum + go func() { + testObject.errorChan <- nil + }() + return testObject +} + +func tmpKeyStore(encrypted bool) (string, *keystore.KeyStore, error) { + d, err := ioutil.TempDir("", "eth-keystore-test") + if err != nil { + return "", nil, err + } + new := keystore.NewPlaintextKeyStore + if encrypted { + new = func(kd string) *keystore.KeyStore { + return keystore.NewKeyStore(kd, keystore.LightScryptN, keystore.LightScryptP) + } + } + return d, new(d), err +} + +func TestPermissionCtrl_whenUpdateFile(t *testing.T) { + testObject := typicalPermissionCtrl(t) + assert.NoError(t, testObject.AfterStart()) + + err := testObject.populateInitPermissions() + assert.NoError(t, err) + + d, _ := ioutil.TempDir("", "qdata") + defer os.RemoveAll(d) + + testObject.dataDir = d + testObject.updatePermissionedNodes(arbitraryNode1, NodeAdd) + + permFile, _ := os.Create(d + "/" + "permissioned-nodes.json") + + testObject.updateFile("testFile", arbitraryNode2, NodeAdd, false) + testObject.updateFile(permFile.Name(), arbitraryNode2, NodeAdd, false) + testObject.updateFile(permFile.Name(), arbitraryNode2, NodeAdd, true) + testObject.updateFile(permFile.Name(), arbitraryNode2, NodeAdd, true) + testObject.updateFile(permFile.Name(), arbitraryNode1, NodeAdd, false) + testObject.updateFile(permFile.Name(), arbitraryNode1, NodeDelete, false) + testObject.updateFile(permFile.Name(), arbitraryNode1, NodeDelete, false) + + blob, err := ioutil.ReadFile(permFile.Name()) + var nodeList []string + if err := json.Unmarshal(blob, &nodeList); err != nil { + t.Fatal("Failed to load nodes list from file", "fileName", permFile, "err", err) + return + } + assert.Equal(t, len(nodeList), 1) + testObject.updatePermissionedNodes(arbitraryNode1, NodeAdd) + testObject.updatePermissionedNodes(arbitraryNode1, NodeDelete) + + blob, err = ioutil.ReadFile(permFile.Name()) + if err := json.Unmarshal(blob, &nodeList); err != nil { + t.Fatal("Failed to load nodes list from file", "fileName", permFile, "err", err) + return + } + assert.Equal(t, len(nodeList), 1) + + testObject.updateDisallowedNodes(arbitraryNode2, NodeAdd) + testObject.updateDisallowedNodes(arbitraryNode2, NodeDelete) + blob, err = ioutil.ReadFile(d + "/" + "disallowed-nodes.json") + if err := json.Unmarshal(blob, &nodeList); err != nil { + t.Fatal("Failed to load nodes list from file", "fileName", permFile, "err", err) + return + } + assert.Equal(t, len(nodeList), 0) + +} + +func TestParsePermissionConfig(t *testing.T) { + d, _ := ioutil.TempDir("", "qdata") + defer os.RemoveAll(d) + + _, err := ParsePermissionConfig(d) + assert.True(t, err != nil, "expected file not there error") + + fileName := d + "/permission-config.json" + _, err = os.Create(fileName) + _, err = ParsePermissionConfig(d) + assert.True(t, err != nil, "expected unmarshalling error") + + // write permission-config.json into the temp dir + var tmpPermCofig types.PermissionConfig + tmpPermCofig.NwAdminOrg = arbitraryNetworkAdminOrg + tmpPermCofig.NwAdminRole = arbitraryNetworkAdminRole + tmpPermCofig.OrgAdminRole = arbitraryOrgAdminRole + tmpPermCofig.InterfAddress = common.Address{} + tmpPermCofig.ImplAddress = common.Address{} + tmpPermCofig.UpgrdAddress = common.Address{} + tmpPermCofig.VoterAddress = common.Address{} + tmpPermCofig.RoleAddress = common.Address{} + tmpPermCofig.OrgAddress = common.Address{} + tmpPermCofig.NodeAddress = common.Address{} + tmpPermCofig.SubOrgBreadth = new(big.Int) + tmpPermCofig.SubOrgDepth = new(big.Int) + + blob, err := json.Marshal(tmpPermCofig) + if err := ioutil.WriteFile(fileName, blob, 0644); err != nil { + t.Fatal("Error writing new node info to file", "fileName", fileName, "err", err) + } + _, err = ParsePermissionConfig(d) + assert.True(t, err != nil, "expected sub org depth not set error") + + _ = os.Remove(fileName) + tmpPermCofig.SubOrgBreadth.Set(big.NewInt(4)) + tmpPermCofig.SubOrgDepth.Set(big.NewInt(4)) + blob, _ = json.Marshal(tmpPermCofig) + if err := ioutil.WriteFile(fileName, blob, 0644); err != nil { + t.Fatal("Error writing new node info to file", "fileName", fileName, "err", err) + } + _, err = ParsePermissionConfig(d) + assert.True(t, err != nil, "expected account not given error") + + _ = os.Remove(fileName) + tmpPermCofig.Accounts = append(tmpPermCofig.Accounts, common.StringToAddress("0xed9d02e382b34818e88b88a309c7fe71e65f419d")) + blob, err = json.Marshal(tmpPermCofig) + if err := ioutil.WriteFile(fileName, blob, 0644); err != nil { + t.Fatal("Error writing new node info to file", "fileName", fileName, "err", err) + } + _, err = ParsePermissionConfig(d) + assert.True(t, err != nil, "expected contract address error") + + _ = os.Remove(fileName) + tmpPermCofig.InterfAddress = common.StringToAddress("0xed9d02e382b34818e88b88a309c7fe71e65f419d") + blob, err = json.Marshal(tmpPermCofig) + if err := ioutil.WriteFile(fileName, blob, 0644); err != nil { + t.Fatal("Error writing new node info to file", "fileName", fileName, "err", err) + } + permConfig, err := ParsePermissionConfig(d) + assert.False(t, permConfig.IsEmpty(), "expected non empty object") +} diff --git a/private/constellation/constellation.go b/private/constellation/constellation.go deleted file mode 100644 index a16c9c8417..0000000000 --- a/private/constellation/constellation.go +++ /dev/null @@ -1,118 +0,0 @@ -package constellation - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "time" - - "github.com/patrickmn/go-cache" -) - -type Constellation struct { - node *Client - c *cache.Cache - isConstellationNotInUse bool -} - -var ( - ErrConstellationIsntInit = errors.New("Constellation not in use") -) - -func (g *Constellation) Send(data []byte, from string, to []string) (out []byte, err error) { - if g.isConstellationNotInUse { - return nil, ErrConstellationIsntInit - } - out, err = g.node.SendPayload(data, from, to) - if err != nil { - return nil, err - } - g.c.Set(string(out), data, cache.DefaultExpiration) - return out, nil -} - -func (g *Constellation) SendSignedTx(data []byte, to []string) (out []byte, err error) { - if g.isConstellationNotInUse { - return nil, ErrConstellationIsntInit - } - out, err = g.node.SendSignedPayload(data, to) - if err != nil { - return nil, err - } - return out, nil -} - -func (g *Constellation) Receive(data []byte) ([]byte, error) { - if g.isConstellationNotInUse { - return nil, nil - } - if len(data) == 0 { - return data, nil - } - // Ignore this error since not being a recipient of - // a payload isn't an error. - // TODO: Return an error if it's anything OTHER than - // 'you are not a recipient.' - dataStr := string(data) - x, found := g.c.Get(dataStr) - if found { - return x.([]byte), nil - } - pl, _ := g.node.ReceivePayload(data) - g.c.Set(dataStr, pl, cache.DefaultExpiration) - return pl, nil -} - -func New(path string) (*Constellation, error) { - info, err := os.Lstat(path) - if err != nil { - return nil, err - } - // We accept either the socket or a configuration file that points to - // a socket. - isSocket := info.Mode()&os.ModeSocket != 0 - if !isSocket { - cfg, err := LoadConfig(path) - if err != nil { - return nil, err - } - path = filepath.Join(cfg.WorkDir, cfg.Socket) - } - err = RunNode(path) - if err != nil { - return nil, err - } - n, err := NewClient(path) - if err != nil { - return nil, err - } - return &Constellation{ - node: n, - c: cache.New(5*time.Minute, 5*time.Minute), - isConstellationNotInUse: false, - }, nil -} - -func MustNew(path string) *Constellation { - if strings.EqualFold(path, "ignore") { - return &Constellation{ - node: nil, - c: nil, - isConstellationNotInUse: true, - } - } - g, err := New(path) - if err != nil { - panic(fmt.Sprintf("MustNew: Failed to connect to Constellation (%s): %v", path, err)) - } - return g -} - -func MaybeNew(path string) *Constellation { - if path == "" { - return nil - } - return MustNew(path) -} diff --git a/private/private.go b/private/private.go index bcbad08da8..7f1bd734d6 100644 --- a/private/private.go +++ b/private/private.go @@ -3,7 +3,7 @@ package private import ( "os" - "github.com/ethereum/go-ethereum/private/constellation" + "github.com/ethereum/go-ethereum/private/privatetransactionmanager" ) type PrivateTransactionManager interface { @@ -17,7 +17,7 @@ func FromEnvironmentOrNil(name string) PrivateTransactionManager { if cfgPath == "" { return nil } - return constellation.MustNew(cfgPath) + return privatetransactionmanager.MustNew(cfgPath) } var P = FromEnvironmentOrNil("PRIVATE_CONFIG") diff --git a/private/constellation/config.go b/private/privatetransactionmanager/config.go similarity index 93% rename from private/constellation/config.go rename to private/privatetransactionmanager/config.go index dba0fe32ef..ec9643483a 100644 --- a/private/constellation/config.go +++ b/private/privatetransactionmanager/config.go @@ -1,4 +1,4 @@ -package constellation +package privatetransactionmanager import ( "github.com/BurntSushi/toml" diff --git a/private/constellation/node.go b/private/privatetransactionmanager/node.go similarity index 96% rename from private/constellation/node.go rename to private/privatetransactionmanager/node.go index 50263aae65..f9af70c9c5 100644 --- a/private/constellation/node.go +++ b/private/privatetransactionmanager/node.go @@ -1,4 +1,4 @@ -package constellation +package privatetransactionmanager import ( "bytes" @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/tv42/httpunix" "io" "io/ioutil" "net/http" @@ -14,6 +13,8 @@ import ( "os/exec" "strings" "time" + + "github.com/tv42/httpunix" ) func launchNode(cfgPath string) (*exec.Cmd, error) { @@ -55,7 +56,7 @@ func RunNode(socketPath string) error { if res.StatusCode == 200 { return nil } - return errors.New("Constellation Node API did not respond to upcheck request") + return errors.New("private transaction manager did not respond to upcheck request") } type Client struct { diff --git a/private/privatetransactionmanager/tx_manager.go b/private/privatetransactionmanager/tx_manager.go new file mode 100644 index 0000000000..1a1107e1bf --- /dev/null +++ b/private/privatetransactionmanager/tx_manager.go @@ -0,0 +1,111 @@ +package privatetransactionmanager + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "time" + + "github.com/patrickmn/go-cache" +) + +type PrivateTransactionManager struct { + node *Client + c *cache.Cache + isPrivateTransactionManagerNotInUse bool +} + +var ( + errPrivateTransactionManagerNotUsed = errors.New("private transaction manager not in use") +) + +func (g *PrivateTransactionManager) Send(data []byte, from string, to []string) (out []byte, err error) { + if g.isPrivateTransactionManagerNotInUse { + return nil, errPrivateTransactionManagerNotUsed + } + out, err = g.node.SendPayload(data, from, to) + if err != nil { + return nil, err + } + g.c.Set(string(out), data, cache.DefaultExpiration) + return out, nil +} + +func (g *PrivateTransactionManager) SendSignedTx(data []byte, to []string) (out []byte, err error) { + if g.isPrivateTransactionManagerNotInUse { + return nil, errPrivateTransactionManagerNotUsed + } + out, err = g.node.SendSignedPayload(data, to) + if err != nil { + return nil, err + } + return out, nil +} + +func (g *PrivateTransactionManager) Receive(data []byte) ([]byte, error) { + if g.isPrivateTransactionManagerNotInUse { + return nil, nil + } + if len(data) == 0 { + return data, nil + } + // Ignore this error since not being a recipient of + // a payload isn't an error. + // TODO: Return an error if it's anything OTHER than + // 'you are not a recipient.' + dataStr := string(data) + x, found := g.c.Get(dataStr) + if found { + return x.([]byte), nil + } + pl, _ := g.node.ReceivePayload(data) + g.c.Set(dataStr, pl, cache.DefaultExpiration) + return pl, nil +} + +func New(path string) (*PrivateTransactionManager, error) { + info, err := os.Lstat(path) + if err != nil { + return nil, err + } + // We accept either the socket or a configuration file that points to + // a socket. + isSocket := info.Mode()&os.ModeSocket != 0 + if !isSocket { + cfg, err := LoadConfig(path) + if err != nil { + return nil, err + } + path = filepath.Join(cfg.WorkDir, cfg.Socket) + } + err = RunNode(path) + if err != nil { + return nil, err + } + n, err := NewClient(path) + if err != nil { + return nil, err + } + return &PrivateTransactionManager{ + node: n, + c: cache.New(5*time.Minute, 5*time.Minute), + isPrivateTransactionManagerNotInUse: false, + }, nil +} + +func MustNew(path string) *PrivateTransactionManager { + if strings.EqualFold(path, "ignore") { + return &PrivateTransactionManager{ + node: nil, + c: nil, + isPrivateTransactionManagerNotInUse: true, + } + } + g, err := New(path) + if err != nil { + panic(fmt.Sprintf("MustNew: Failed to connect to private transaction manager (%s): %v", path, err)) + } + return g +} diff --git a/raft/api.go b/raft/api.go index 55c652571d..c1c38c532f 100755 --- a/raft/api.go +++ b/raft/api.go @@ -23,23 +23,58 @@ func (s *PublicRaftAPI) Role() string { } func (s *PublicRaftAPI) AddPeer(enodeId string) (uint16, error) { - return s.raftService.raftProtocolManager.ProposeNewPeer(enodeId) + return s.raftService.raftProtocolManager.ProposeNewPeer(enodeId, false) } -func (s *PublicRaftAPI) RemovePeer(raftId uint16) { - s.raftService.raftProtocolManager.ProposePeerRemoval(raftId) +func (s *PublicRaftAPI) AddLearner(enodeId string) (uint16, error) { + return s.raftService.raftProtocolManager.ProposeNewPeer(enodeId, true) +} + +func (s *PublicRaftAPI) PromoteToPeer(raftId uint16) (bool, error) { + return s.raftService.raftProtocolManager.PromoteToPeer(raftId) +} + +func (s *PublicRaftAPI) RemovePeer(raftId uint16) error { + return s.raftService.raftProtocolManager.ProposePeerRemoval(raftId) } func (s *PublicRaftAPI) Leader() (string, error) { addr, err := s.raftService.raftProtocolManager.LeaderAddress() - if nil != err { + if err != nil { return "", err } return addr.NodeId.String(), nil } -func (s *PublicRaftAPI) Cluster() []*Address { +func (s *PublicRaftAPI) Cluster() ([]ClusterInfo, error) { nodeInfo := s.raftService.raftProtocolManager.NodeInfo() - return append(nodeInfo.PeerAddresses, nodeInfo.Address) + if nodeInfo.Role == "" { + return []ClusterInfo{}, nil + } + leaderAddr, err := s.raftService.raftProtocolManager.LeaderAddress() + if err != nil { + if err == errNoLeaderElected && s.Role() == "" { + return []ClusterInfo{}, nil + } + return []ClusterInfo{}, err + } + peerAddresses := append(nodeInfo.PeerAddresses, nodeInfo.Address) + clustInfo := make([]ClusterInfo, len(peerAddresses)) + for i, a := range peerAddresses { + role := "" + if a.RaftId == leaderAddr.RaftId { + role = "minter" + } else if s.raftService.raftProtocolManager.isLearner(a.RaftId) { + role = "learner" + } else if s.raftService.raftProtocolManager.isVerifier(a.RaftId) { + role = "verifier" + } + clustInfo[i] = ClusterInfo{*a, role} + } + return clustInfo, nil +} + +func (s *PublicRaftAPI) GetRaftId(enodeId string) (uint16, error) { + return s.raftService.raftProtocolManager.FetchRaftId(enodeId) } diff --git a/raft/backend.go b/raft/backend.go index d9e54fb5ba..ca3d6644b8 100644 --- a/raft/backend.go +++ b/raft/backend.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/ethdb" @@ -31,27 +32,29 @@ type RaftService struct { startPeers []*enode.Node // we need an event mux to instantiate the blockchain - eventMux *event.TypeMux - minter *minter - nodeKey *ecdsa.PrivateKey + eventMux *event.TypeMux + minter *minter + nodeKey *ecdsa.PrivateKey + calcGasLimitFunc func(block *types.Block) uint64 } -func New(ctx *node.ServiceContext, chainConfig *params.ChainConfig, raftId, raftPort uint16, joinExisting bool, blockTime time.Duration, e *eth.Ethereum, startPeers []*enode.Node, datadir string) (*RaftService, error) { +func New(ctx *node.ServiceContext, chainConfig *params.ChainConfig, raftId, raftPort uint16, joinExisting bool, blockTime time.Duration, e *eth.Ethereum, startPeers []*enode.Node, datadir string, useDns bool) (*RaftService, error) { service := &RaftService{ - eventMux: ctx.EventMux, - chainDb: e.ChainDb(), - blockchain: e.BlockChain(), - txPool: e.TxPool(), - accountManager: e.AccountManager(), - downloader: e.Downloader(), - startPeers: startPeers, - nodeKey: ctx.NodeKey(), + eventMux: ctx.EventMux, + chainDb: e.ChainDb(), + blockchain: e.BlockChain(), + txPool: e.TxPool(), + accountManager: e.AccountManager(), + downloader: e.Downloader(), + startPeers: startPeers, + nodeKey: ctx.NodeKey(), + calcGasLimitFunc: e.CalcGasLimit, } service.minter = newMinter(chainConfig, service, blockTime) var err error - if service.raftProtocolManager, err = NewProtocolManager(raftId, raftPort, service.blockchain, service.eventMux, startPeers, joinExisting, datadir, service.minter, service.downloader); err != nil { + if service.raftProtocolManager, err = NewProtocolManager(raftId, raftPort, service.blockchain, service.eventMux, startPeers, joinExisting, datadir, service.minter, service.downloader, useDns); err != nil { return nil, err } diff --git a/raft/handler.go b/raft/handler.go index f707c6370d..8ee70b7b3b 100755 --- a/raft/handler.go +++ b/raft/handler.go @@ -1,8 +1,10 @@ package raft import ( + "context" "errors" "fmt" + "net" "net/http" "net/url" "os" @@ -10,29 +12,26 @@ import ( "sync" "time" - "golang.org/x/net/context" - + "github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/pkg/fileutil" + raftTypes "github.com/coreos/etcd/pkg/types" + etcdRaft "github.com/coreos/etcd/raft" + "github.com/coreos/etcd/raft/raftpb" + "github.com/coreos/etcd/rafthttp" "github.com/coreos/etcd/snap" "github.com/coreos/etcd/wal" + mapset "github.com/deckarep/golang-set" + "github.com/syndtr/goleveldb/leveldb" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/rlp" - - "github.com/coreos/etcd/etcdserver/stats" - raftTypes "github.com/coreos/etcd/pkg/types" - etcdRaft "github.com/coreos/etcd/raft" - "github.com/coreos/etcd/raft/raftpb" - "github.com/coreos/etcd/rafthttp" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/syndtr/goleveldb/leveldb" - - "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/rlp" ) type ProtocolManager struct { @@ -59,6 +58,7 @@ type ProtocolManager struct { // P2P transport p2pServer *p2p.Server // Initialized in start() + useDns bool // Blockchain services blockchain *core.BlockChain @@ -93,11 +93,13 @@ type ProtocolManager struct { raftStorage *etcdRaft.MemoryStorage // Volatile raft storage } +var errNoLeaderElected = errors.New("no leader is currently elected") + // // Public interface // -func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockChain, mux *event.TypeMux, bootstrapNodes []*enode.Node, joinExisting bool, datadir string, minter *minter, downloader *downloader.Downloader) (*ProtocolManager, error) { +func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockChain, mux *event.TypeMux, bootstrapNodes []*enode.Node, joinExisting bool, datadir string, minter *minter, downloader *downloader.Downloader, useDns bool) (*ProtocolManager, error) { waldir := fmt.Sprintf("%s/raft-wal", datadir) snapdir := fmt.Sprintf("%s/raft-snap", datadir) quorumRaftDbLoc := fmt.Sprintf("%s/quorum-raft-state", datadir) @@ -110,7 +112,7 @@ func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockCh joinExisting: joinExisting, blockchain: blockchain, eventMux: mux, - blockProposalC: make(chan *types.Block), + blockProposalC: make(chan *types.Block, 10), confChangeProposalC: make(chan raftpb.ConfChange), httpstopc: make(chan struct{}), httpdonec: make(chan struct{}), @@ -123,6 +125,7 @@ func NewProtocolManager(raftId uint16, raftPort uint16, blockchain *core.BlockCh raftStorage: etcdRaft.NewMemoryStorage(), minter: minter, downloader: downloader, + useDns: useDns, } if db, err := openQuorumRaftDb(quorumRaftDbLoc); err != nil { @@ -140,6 +143,8 @@ func (pm *ProtocolManager) Start(p2pServer *p2p.Server) { pm.p2pServer = p2pServer pm.minedBlockSub = pm.eventMux.Subscribe(core.NewMinedBlockEvent{}) pm.startRaft() + // update raft peers info to p2p server + pm.p2pServer.SetCheckPeerInRaft(pm.peerExist) go pm.minedBroadcastLoop() } @@ -186,11 +191,13 @@ func (pm *ProtocolManager) NodeInfo() *RaftNodeInfo { pm.mu.RLock() // as we read role and peers defer pm.mu.RUnlock() - var roleDescription string + roleDescription := "" if pm.role == minterRole { roleDescription = "minter" - } else { + } else if pm.isVerifierNode() { roleDescription = "verifier" + } else if pm.isLearnerNode() { + roleDescription = "learner" } peerAddresses := make([]*Address, len(pm.peers)) @@ -302,13 +309,31 @@ func (pm *ProtocolManager) isNodeAlreadyInCluster(node *enode.Node) error { return nil } -func (pm *ProtocolManager) ProposeNewPeer(enodeId string) (uint16, error) { +func (pm *ProtocolManager) peerExist(node *enode.Node) bool { + pm.mu.RLock() + defer pm.mu.RUnlock() + + for _, p := range pm.peers { + if node.ID() == p.p2pNode.ID() { + return true + } + } + return false +} + +func (pm *ProtocolManager) ProposeNewPeer(enodeId string, isLearner bool) (uint16, error) { + if pm.isLearnerNode() { + return 0, errors.New("learner node can't add peer or learner") + } + parsedUrl, _ := url.Parse(enodeId) node, err := enode.ParseV4(enodeId) if err != nil { return 0, err } - if len(node.IP()) != 4 { + //use the hostname instead of the IP, since if DNS is not enabled, the hostname should *be* the IP + ip := net.ParseIP(parsedUrl.Hostname()) + if !pm.useDns && (len(ip.To4()) != 4) { return 0, fmt.Errorf("expected IPv4 address (with length 4), but got IP of length %v", len(node.IP())) } @@ -321,22 +346,48 @@ func (pm *ProtocolManager) ProposeNewPeer(enodeId string) (uint16, error) { } raftId := pm.nextRaftId() - address := newAddress(raftId, node.RaftPort(), node) + address := newAddress(raftId, node.RaftPort(), node, pm.useDns) + + confChangeType := raftpb.ConfChangeAddNode + + if isLearner { + confChangeType = raftpb.ConfChangeAddLearnerNode + } pm.confChangeProposalC <- raftpb.ConfChange{ - Type: raftpb.ConfChangeAddNode, + Type: confChangeType, NodeID: uint64(raftId), - Context: address.toBytes(), + Context: address.toBytes(pm.useDns), } return raftId, nil } -func (pm *ProtocolManager) ProposePeerRemoval(raftId uint16) { +func (pm *ProtocolManager) ProposePeerRemoval(raftId uint16) error { + if pm.isLearnerNode() && raftId != pm.raftId { + return errors.New("learner node can't remove other peer") + } pm.confChangeProposalC <- raftpb.ConfChange{ Type: raftpb.ConfChangeRemoveNode, NodeID: uint64(raftId), } + return nil +} + +func (pm *ProtocolManager) PromoteToPeer(raftId uint16) (bool, error) { + if pm.isLearnerNode() { + return false, errors.New("learner node can't promote to peer") + } + + if !pm.isLearner(raftId) { + return false, fmt.Errorf("%d is not a learner. only learner can be promoted to peer", raftId) + } + + pm.confChangeProposalC <- raftpb.ConfChange{ + Type: raftpb.ConfChangeAddNode, + NodeID: uint64(raftId), + } + return true, nil } // @@ -392,8 +443,9 @@ func (pm *ProtocolManager) startRaft() { walExisted := wal.Exist(pm.waldir) lastAppliedIndex := pm.loadAppliedIndex() - ss := &stats.ServerStats{} - ss.Initialize() + id := raftTypes.ID(pm.raftId).String() + ss := stats.NewServerStats(id, id) + pm.transport = &rafthttp.Transport{ ID: raftTypes.ID(pm.raftId), ClusterID: 0x1000, @@ -413,9 +465,40 @@ func (pm *ProtocolManager) startRaft() { maybeRaftSnapshot = pm.loadSnapshot() // re-establishes peer connections } - pm.wal = pm.replayWAL(maybeRaftSnapshot) + loadedWal, entries := pm.replayWAL(maybeRaftSnapshot) + pm.wal = loadedWal if walExisted { + + // If we shutdown but didn't manage to flush the state to disk, then it will be the case that we will only sync + // up to the snapshot. In this case, we can replay the raft entries that we have in saved to replay the blocks + // back into our chain. We output errors but cannot do much if one occurs, since we can't fork to a different + // chain and all other nodes in the network have confirmed these blocks + if maybeRaftSnapshot != nil { + currentChainHead := pm.blockchain.CurrentBlock().Number() + for _, entry := range entries { + if entry.Type == raftpb.EntryNormal { + var block types.Block + if err := rlp.DecodeBytes(entry.Data, &block); err != nil { + log.Error("error decoding block: ", "err", err) + continue + } + + if thisBlockHead := pm.blockchain.GetBlockByHash(block.Hash()); thisBlockHead != nil { + // check if the block is already existing in the local chain + // and the block number is greater than current chain head + if thisBlockHeadNum := thisBlockHead.Number(); thisBlockHeadNum.Cmp(currentChainHead) > 0 { + // insert the block only if its already seen + blocks := []*types.Block{&block} + if _, err := pm.blockchain.InsertChain(blocks); err != nil { + log.Error("error inserting the block into the chain", "number", block.NumberU64(), "hash", block.Hash(), "err", err) + } + } + } + } + } + } + if hardState, _, err := pm.raftStorage.InitialState(); err != nil { panic(fmt.Sprintf("failed to read initial state from raft while restarting: %v", err)) } else { @@ -426,6 +509,19 @@ func (pm *ProtocolManager) startRaft() { // the single call to `pm.applyNewChainHead` for more context. lastAppliedIndex = lastPersistedCommittedIndex } + + // fix raft applied index out of range + firstIndex, err := pm.raftStorage.FirstIndex() + if err != nil { + panic(fmt.Sprintf("failed to read last persisted applied index from raft while restarting: %v", err)) + } + lastPersistedAppliedIndex := firstIndex - 1 + if lastPersistedAppliedIndex > lastAppliedIndex { + log.Debug("set lastAppliedIndex to lastPersistedAppliedIndex", "last applied index", lastAppliedIndex, "last persisted applied index", lastPersistedAppliedIndex) + + lastAppliedIndex = lastPersistedAppliedIndex + pm.advanceAppliedIndex(lastAppliedIndex) + } } } @@ -469,6 +565,7 @@ func (pm *ProtocolManager) startRaft() { if walExisted { log.Info("remounting an existing raft log; connecting to peers.") + pm.unsafeRawNode = etcdRaft.RestartNode(raftConfig) } else if pm.joinExisting { log.Info("newly joining an existing cluster; waiting for connections.") @@ -491,10 +588,9 @@ func (pm *ProtocolManager) startRaft() { for _, peerAddress := range peerAddresses { pm.addPeer(peerAddress) } - pm.unsafeRawNode = etcdRaft.StartNode(raftConfig, raftPeers) } - + log.Info("raft node started") go pm.serveRaft() go pm.serveLocalProposals() go pm.eventLoop() @@ -505,11 +601,10 @@ func (pm *ProtocolManager) setLocalAddress(addr *Address) { pm.mu.Lock() pm.address = addr pm.mu.Unlock() - // By setting `URLs` on the raft transport, we advertise our URL (in an HTTP // header) to any recipient. This is necessary for a newcomer to the cluster // to be able to accept a snapshot from us to bootstrap them. - if urls, err := raftTypes.NewURLs([]string{raftUrl(addr)}); err == nil { + if urls, err := raftTypes.NewURLs([]string{pm.raftUrl(addr)}); err == nil { pm.transport.URLs = urls } else { panic(fmt.Sprintf("error: could not create URL from local address: %v", addr)) @@ -536,6 +631,36 @@ func (pm *ProtocolManager) serveRaft() { close(pm.httpdonec) } +func (pm *ProtocolManager) isLearner(rid uint16) bool { + pm.mu.RLock() + defer pm.mu.RUnlock() + for _, n := range pm.confState.Learners { + if uint16(n) == rid { + return true + } + } + return false +} + +func (pm *ProtocolManager) isLearnerNode() bool { + return pm.isLearner(pm.raftId) +} + +func (pm *ProtocolManager) isVerifierNode() bool { + return pm.isVerifier(pm.raftId) +} + +func (pm *ProtocolManager) isVerifier(rid uint16) bool { + pm.mu.RLock() + defer pm.mu.RUnlock() + for _, n := range pm.confState.Nodes { + if uint16(n) == rid { + return true + } + } + return false +} + func (pm *ProtocolManager) handleRoleChange(roleC <-chan interface{}) { for { select { @@ -550,7 +675,11 @@ func (pm *ProtocolManager) handleRoleChange(roleC <-chan interface{}) { log.EmitCheckpoint(log.BecameMinter) pm.minter.start() } else { // verifier - log.EmitCheckpoint(log.BecameVerifier) + if pm.isVerifierNode() { + log.EmitCheckpoint(log.BecameVerifier) + } else { + log.EmitCheckpoint(log.BecameLearner) + } pm.minter.stop() } @@ -638,8 +767,21 @@ func (pm *ProtocolManager) entriesToApply(allEntries []raftpb.Entry) (entriesToA return } -func raftUrl(address *Address) string { - return fmt.Sprintf("http://%s:%d", address.Ip, address.RaftPort) +func (pm *ProtocolManager) raftUrl(address *Address) string { + if !pm.useDns { + parsedIp := net.ParseIP(address.Hostname) + return fmt.Sprintf("http://%s:%d", parsedIp.To4(), address.RaftPort) + } + + if parsedIp := net.ParseIP(address.Hostname); parsedIp != nil { + if ipv4 := parsedIp.To4(); ipv4 != nil { + //this is an IPv4 address + return fmt.Sprintf("http://%s:%d", ipv4, address.RaftPort) + } + //this is an IPv6 address + return fmt.Sprintf("http://[%s]:%d", parsedIp, address.RaftPort) + } + return fmt.Sprintf("http://%s:%d", address.Hostname, address.RaftPort) } func (pm *ProtocolManager) addPeer(address *Address) { @@ -656,11 +798,11 @@ func (pm *ProtocolManager) addPeer(address *Address) { } // Add P2P connection: - p2pNode := enode.NewV4(pubKey, address.Ip, 0, int(address.P2pPort), int(address.RaftPort)) + p2pNode := enode.NewV4Hostname(pubKey, address.Hostname, int(address.P2pPort), 0, int(address.RaftPort)) pm.p2pServer.AddPeer(p2pNode) // Add raft transport connection: - pm.transport.AddPeer(raftTypes.ID(raftId), []string{raftUrl(address)}) + pm.transport.AddPeer(raftTypes.ID(raftId), []string{pm.raftUrl(address)}) pm.peers[raftId] = &Peer{address, p2pNode} } @@ -700,8 +842,8 @@ func (pm *ProtocolManager) eventLoop() { case <-ticker.C: pm.rawNode().Tick() - // when the node is first ready it gives us entries to commit and messages - // to immediately publish + // when the node is first ready it gives us entries to commit and messages + // to immediately publish case rd := <-pm.rawNode().Ready(): pm.wal.Save(rd.HardState, rd.Entries) @@ -749,7 +891,11 @@ func (pm *ProtocolManager) eventLoop() { headBlockHash := pm.blockchain.CurrentBlock().Hash() log.Warn("not applying already-applied block", "block hash", block.Hash(), "parent", block.ParentHash(), "head", headBlockHash) } else { - pm.applyNewChainHead(&block) + if !pm.applyNewChainHead(&block) { + // return false only if insert chain is interrupted + // stop eventloop + return + } } case raftpb.EntryConfChange: @@ -758,26 +904,30 @@ func (pm *ProtocolManager) eventLoop() { raftId := uint16(cc.NodeID) pm.confState = *pm.rawNode().ApplyConfChange(cc) - + log.Info("confChange", "confState", pm.confState) forceSnapshot := false switch cc.Type { - case raftpb.ConfChangeAddNode: + case raftpb.ConfChangeAddNode, raftpb.ConfChangeAddLearnerNode: + confChangeTypeName := raftpb.ConfChangeType_name[int32(cc.Type)] + log.Info(confChangeTypeName, "raft id", raftId) if pm.isRaftIdRemoved(raftId) { - log.Info("ignoring ConfChangeAddNode for permanently-removed peer", "raft id", raftId) - } else if peer := pm.peers[raftId]; peer != nil && raftId <= uint16(len(pm.bootstrapNodes)) { + log.Info("ignoring "+confChangeTypeName+" for permanently-removed peer", "raft id", raftId) + } else if pm.isRaftIdUsed(raftId) && raftId <= uint16(len(pm.bootstrapNodes)) { // See initial cluster logic in startRaft() for more information. - log.Info("ignoring expected ConfChangeAddNode for initial peer", "raft id", raftId) - + log.Info("ignoring expected "+confChangeTypeName+" for initial peer", "raft id", raftId) // We need a snapshot to exist to reconnect to peers on start-up after a crash. forceSnapshot = true - } else if pm.isRaftIdUsed(raftId) { - log.Info("ignoring ConfChangeAddNode for already-used raft ID", "raft id", raftId) - } else { - log.Info("adding peer due to ConfChangeAddNode", "raft id", raftId) - + } else { // add peer or add learner or promote learner to voter forceSnapshot = true - pm.addPeer(bytesToAddress(cc.Context)) + //if raft id exists as peer, you are promoting learner to peer + if pm.isRaftIdUsed(raftId) { + log.Info("promote learner node to voter node", "raft id", raftId) + } else { + //if raft id does not exist, you are adding peer/learner + log.Info("add peer/learner -> "+confChangeTypeName, "raft id", raftId) + pm.addPeer(bytesToAddress(cc.Context)) + } } case raftpb.ConfChangeRemoveNode: @@ -848,10 +998,10 @@ func (pm *ProtocolManager) makeInitialRaftPeers() (raftPeers []etcdRaft.Peer, pe // We initially get the raftPort from the enode ID's query string. As an alternative, we can move away from // requiring the use of static peers for the initial set, and load them from e.g. another JSON file which // contains pairs of enodes and raft ports, or we can get this initial peer list from commandline flags. - address := newAddress(raftId, node.RaftPort(), node) + address := newAddress(raftId, node.RaftPort(), node, pm.useDns) raftPeers[i] = etcdRaft.Peer{ ID: uint64(raftId), - Context: address.toBytes(), + Context: address.toBytes(pm.useDns), } if raftId == pm.raftId { @@ -865,15 +1015,11 @@ func (pm *ProtocolManager) makeInitialRaftPeers() (raftPeers []etcdRaft.Peer, pe return } -func sleep(duration time.Duration) { - <-time.NewTimer(duration).C -} - func blockExtendsChain(block *types.Block, chain *core.BlockChain) bool { return block.ParentHash() == chain.CurrentBlock().Hash() } -func (pm *ProtocolManager) applyNewChainHead(block *types.Block) { +func (pm *ProtocolManager) applyNewChainHead(block *types.Block) bool { if !blockExtendsChain(block, pm.blockchain) { headBlock := pm.blockchain.CurrentBlock() @@ -894,11 +1040,16 @@ func (pm *ProtocolManager) applyNewChainHead(block *types.Block) { _, err := pm.blockchain.InsertChain([]*types.Block{block}) if err != nil { + if err == core.ErrAbortBlocksProcessing { + log.Error(fmt.Sprintf("failed to extend chain: %s", err.Error())) + return false + } panic(fmt.Sprintf("failed to extend chain: %s", err.Error())) } log.EmitCheckpoint(log.BlockCreated, "block", fmt.Sprintf("%x", block.Hash())) } + return true } // Sets new appliedIndex in-memory, *and* writes this appliedIndex to LevelDB. @@ -928,5 +1079,19 @@ func (pm *ProtocolManager) LeaderAddress() (*Address, error) { return l.address, nil } // We expect to reach this if pm.leader is 0, which is how etcd denotes the lack of a leader. - return nil, errors.New("no leader is currently elected") + return nil, errNoLeaderElected +} + +// Returns the raft id for a given enodeId +func (pm *ProtocolManager) FetchRaftId(enodeId string) (uint16, error) { + node, err := enode.ParseV4(enodeId) + if err != nil { + return 0, err + } + for raftId, peer := range pm.peers { + if peer.p2pNode.ID() == node.ID() { + return raftId, nil + } + } + return 0, fmt.Errorf("node not found in the cluster: %v", enodeId) } diff --git a/raft/handler_test.go b/raft/handler_test.go new file mode 100644 index 0000000000..9ccca03775 --- /dev/null +++ b/raft/handler_test.go @@ -0,0 +1,199 @@ +package raft + +import ( + "crypto/ecdsa" + "encoding/binary" + "fmt" + "io/ioutil" + "net" + "os" + "reflect" + "testing" + "time" + "unsafe" + + "github.com/coreos/etcd/wal" + "github.com/coreos/etcd/wal/walpb" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" +) + +// pm.advanceAppliedIndex() and state updates are in different +// transaction boundaries hence there's a probablity that they are +// out of sync due to premature shutdown +func TestProtocolManager_whenAppliedIndexOutOfSync(t *testing.T) { + logger := log.New() + logger.SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) + tmpWorkingDir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + defer func() { + _ = os.RemoveAll(tmpWorkingDir) + }() + count := 3 + ports := make([]uint16, count) + nodeKeys := make([]*ecdsa.PrivateKey, count) + peers := make([]*enode.Node, count) + for i := 0; i < count; i++ { + ports[i] = nextPort(t) + nodeKeys[i] = mustNewNodeKey(t) + peers[i] = enode.NewV4(&(nodeKeys[i].PublicKey), net.IPv4(127, 0, 0, 1), 0, 0, int(ports[i])) + } + raftNodes := make([]*RaftService, count) + for i := 0; i < count; i++ { + if s, err := startRaftNode(uint16(i+1), ports[i], tmpWorkingDir, nodeKeys[i], peers); err != nil { + t.Fatal(err) + } else { + raftNodes[i] = s + } + } + waitFunc := func() { + for { + time.Sleep(10 * time.Millisecond) + for i := 0; i < count; i++ { + if raftNodes[i].raftProtocolManager.role == minterRole { + return + } + } + } + } + waitFunc() + logger.Debug("stop the cluster") + for i := 0; i < count; i++ { + if err := raftNodes[i].Stop(); err != nil { + t.Fatal(err) + } + // somehow the wal dir is still being locked that causes failures in subsequent start + // we need to check here to make sure everything is fully stopped + for isWalDirStillLocked(fmt.Sprintf("%s/node%d/raft-wal", tmpWorkingDir, i+1)) { + logger.Debug("sleep...", "i", i) + time.Sleep(10 * time.Millisecond) + } + logger.Debug("node stopped", "id", i) + } + logger.Debug("update applied index") + // update the index to mimic the issue (set applied index behind for node 0) + if err := writeAppliedIndex(tmpWorkingDir, 0, 1); err != nil { + t.Fatal(err) + } + //time.Sleep(3 * time.Second) + logger.Debug("restart the cluster") + for i := 0; i < count; i++ { + if s, err := startRaftNode(uint16(i+1), ports[i], tmpWorkingDir, nodeKeys[i], peers); err != nil { + t.Fatal(err) + } else { + raftNodes[i] = s + } + } + waitFunc() +} + +func isWalDirStillLocked(walDir string) bool { + var snap walpb.Snapshot + w, err := wal.Open(walDir, snap) + if err != nil { + return true + } + defer func() { + _ = w.Close() + }() + return false +} + +func writeAppliedIndex(workingDir string, node int, index uint64) error { + db, err := openQuorumRaftDb(fmt.Sprintf("%s/node%d/quorum-raft-state", workingDir, node+1)) + if err != nil { + return err + } + defer func() { + _ = db.Close() + }() + buf := make([]byte, 8) + binary.LittleEndian.PutUint64(buf, index) + if err := db.Put(appliedDbKey, buf, noFsync); err != nil { + return err + } + return nil +} + +func mustNewNodeKey(t *testing.T) *ecdsa.PrivateKey { + k, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + return k +} + +func nextPort(t *testing.T) uint16 { + listener, err := net.Listen("tcp", ":0") + if err != nil { + t.Fatal(err) + } + return uint16(listener.Addr().(*net.TCPAddr).Port) +} + +func prepareServiceContext(key *ecdsa.PrivateKey) (ctx *node.ServiceContext, cfg *node.Config, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%s", r) + ctx = nil + cfg = nil + } + }() + cfg = &node.Config{ + P2P: p2p.Config{ + PrivateKey: key, + }, + } + ctx = &node.ServiceContext{ + EventMux: new(event.TypeMux), + } + // config is private field so we need some workaround to set the value + configField := reflect.ValueOf(ctx).Elem().FieldByName("config") + configField = reflect.NewAt(configField.Type(), unsafe.Pointer(configField.UnsafeAddr())).Elem() + configField.Set(reflect.ValueOf(cfg)) + return +} + +func startRaftNode(id, port uint16, tmpWorkingDir string, key *ecdsa.PrivateKey, nodes []*enode.Node) (*RaftService, error) { + datadir := fmt.Sprintf("%s/node%d", tmpWorkingDir, id) + + ctx, _, err := prepareServiceContext(key) + if err != nil { + return nil, err + } + + e, err := eth.New(ctx, ð.Config{ + Genesis: &core.Genesis{Config: params.QuorumTestChainConfig}, + }) + if err != nil { + return nil, err + } + + s, err := New(ctx, params.QuorumTestChainConfig, id, port, false, 100*time.Millisecond, e, nodes, datadir, false) + if err != nil { + return nil, err + } + + srv := &p2p.Server{ + Config: p2p.Config{ + PrivateKey: key, + }, + } + if err := srv.Start(); err != nil { + return nil, fmt.Errorf("could not start: %v", err) + } + if err := s.Start(srv); err != nil { + return nil, err + } + + return s, nil +} diff --git a/raft/minter.go b/raft/minter.go index 7aa3ef25dc..373bb28ab8 100644 --- a/raft/minter.go +++ b/raft/minter.go @@ -89,7 +89,7 @@ func newMinter(config *params.ChainConfig, eth *RaftService, blockTime time.Dura speculativeChain: newSpeculativeChain(), invalidRaftOrderingChan: make(chan InvalidRaftOrdering, 1), - chainHeadChan: make(chan core.ChainHeadEvent, 1), + chainHeadChan: make(chan core.ChainHeadEvent, core.GetChainHeadChannleSize()), txPreChan: make(chan core.NewTxsEvent, 4096), } @@ -213,7 +213,7 @@ func throttle(rate time.Duration, f func()) func() { for range ticker.C { <-request.Out() - go f() + f() } }() @@ -262,7 +262,7 @@ func (minter *minter) createWork() *work { ParentHash: parent.Hash(), Number: parentNumber.Add(parentNumber, common.Big1), Difficulty: ethash.CalcDifficulty(minter.config, uint64(tstamp), parent.Header()), - GasLimit: core.CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()), + GasLimit: minter.eth.calcGasLimitFunc(parent), GasUsed: 0, Coinbase: minter.coinbase, Time: big.NewInt(tstamp), diff --git a/raft/minter_test.go b/raft/minter_test.go index 975525ee72..3103103e87 100644 --- a/raft/minter_test.go +++ b/raft/minter_test.go @@ -1,10 +1,17 @@ package raft import ( + "errors" + "fmt" "math/big" + "strings" "testing" "time" + "github.com/coreos/etcd/raft/raftpb" + "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -13,6 +20,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) +const TEST_URL = "enode://3d9ca5956b38557aba991e31cf510d4df641dce9cc26bfeb7de082f0c07abb6ede3a58410c8f249dabeecee4ad3979929ac4c7c496ad20b8cfdd061b7401b4f5@127.0.0.1:21003?discport=0&raftport=50404" + func TestSignHeader(t *testing.T) { //create only what we need to test the seal var testRaftId uint16 = 5 @@ -67,3 +76,130 @@ func TestSignHeader(t *testing.T) { } } + +func TestAddLearner_whenTypical(t *testing.T) { + + raftService := newTestRaftService(t, 1, []uint64{1}, []uint64{}) + + propPeer := func() { + raftid, err := raftService.raftProtocolManager.ProposeNewPeer(TEST_URL, true) + if err != nil { + t.Errorf("propose new peer failed %v\n", err) + } + if raftid != raftService.raftProtocolManager.raftId+1 { + t.Errorf("1. wrong raft id. expected %d got %d\n", raftService.raftProtocolManager.raftId+1, raftid) + } + } + go propPeer() + select { + case confChange := <-raftService.raftProtocolManager.confChangeProposalC: + if confChange.Type != raftpb.ConfChangeAddLearnerNode { + t.Errorf("expected ConfChangeAddLearnerNode but got %s", confChange.Type.String()) + } + if uint16(confChange.NodeID) != raftService.raftProtocolManager.raftId+1 { + t.Errorf("2. wrong raft id. expected %d got %d\n", raftService.raftProtocolManager.raftId+1, uint16(confChange.NodeID)) + } + case <-time.After(time.Millisecond * 200): + t.Errorf("add learner conf change not recieved") + } +} + +func TestPromoteLearnerToPeer_whenTypical(t *testing.T) { + learnerRaftId := uint16(3) + raftService := newTestRaftService(t, 2, []uint64{2}, []uint64{uint64(learnerRaftId)}) + promoteToPeer := func() { + ok, err := raftService.raftProtocolManager.PromoteToPeer(learnerRaftId) + if err != nil || !ok { + t.Errorf("promote learner to peer failed %v\n", err) + } + } + go promoteToPeer() + select { + case confChange := <-raftService.raftProtocolManager.confChangeProposalC: + if confChange.Type != raftpb.ConfChangeAddNode { + t.Errorf("expected ConfChangeAddNode but got %s", confChange.Type.String()) + } + if uint16(confChange.NodeID) != learnerRaftId { + t.Errorf("2. wrong raft id. expected %d got %d\n", learnerRaftId, uint16(confChange.NodeID)) + } + case <-time.After(time.Millisecond * 200): + t.Errorf("add learner conf change not recieved") + } +} + +func TestAddLearnerOrPeer_fromLearner(t *testing.T) { + + raftService := newTestRaftService(t, 3, []uint64{2}, []uint64{3}) + + _, err := raftService.raftProtocolManager.ProposeNewPeer(TEST_URL, true) + + if err == nil { + t.Errorf("learner should not be allowed to add learner or peer") + } + + if err != nil && strings.Index(err.Error(), "learner node can't add peer or learner") == -1 { + t.Errorf("expect error message: propose new peer failed, got: %v\n", err) + } + + _, err = raftService.raftProtocolManager.ProposeNewPeer(TEST_URL, false) + + if err == nil { + t.Errorf("learner should not be allowed to add learner or peer") + } + + if err != nil && strings.Index(err.Error(), "learner node can't add peer or learner") == -1 { + t.Errorf("expect error message: propose new peer failed, got: %v\n", err) + } + +} + +func TestPromoteLearnerToPeer_fromLearner(t *testing.T) { + learnerRaftId := uint16(3) + raftService := newTestRaftService(t, 2, []uint64{1}, []uint64{2, uint64(learnerRaftId)}) + + _, err := raftService.raftProtocolManager.PromoteToPeer(learnerRaftId) + + if err == nil { + t.Errorf("learner should not be allowed to promote to peer") + } + + if err != nil && strings.Index(err.Error(), "learner node can't promote to peer") == -1 { + t.Errorf("expect error message: propose new peer failed, got: %v\n", err) + } + +} + +func enodeId(id string, ip string, raftPort int) string { + return fmt.Sprintf("enode://%s@%s?discport=0&raftport=%d", id, ip, raftPort) +} + +func peerList(url string) (error, []*enode.Node) { + var nodes []*enode.Node + node, err := enode.ParseV4(url) + if err != nil { + return errors.New(fmt.Sprintf("Node URL %s: %v\n", url, err)), nil + } + nodes = append(nodes, node) + return nil, nodes +} + +func newTestRaftService(t *testing.T, raftId uint16, nodes []uint64, learners []uint64) *RaftService { + //create only what we need to test add learner node + config := &node.Config{Name: "unit-test", DataDir: ""} + nodeKey := config.NodeKey() + enodeIdStr := fmt.Sprintf("%x", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:]) + url := enodeId(enodeIdStr, "127.0.0.1:21001", 50401) + err, peers := peerList(url) + if err != nil { + t.Errorf("getting peers failed %v", err) + } + raftProtocolManager := &ProtocolManager{ + raftId: raftId, + bootstrapNodes: peers, + confChangeProposalC: make(chan raftpb.ConfChange), + removedPeers: mapset.NewSet(), + confState: raftpb.ConfState{Nodes: nodes, Learners: learners}, + } + raftService := &RaftService{nodeKey: nodeKey, raftProtocolManager: raftProtocolManager} + return raftService +} diff --git a/raft/peer.go b/raft/peer.go index 0649239100..12b5a6414f 100644 --- a/raft/peer.go +++ b/raft/peer.go @@ -1,14 +1,14 @@ package raft import ( - "io" + "bytes" + "fmt" + "log" "net" - "fmt" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "log" ) // Serializable information about a Peer. Sufficient to build `etcdRaft.Peer` @@ -17,23 +17,44 @@ import ( type Address struct { RaftId uint16 `json:"raftId"` NodeId enode.EnodeID `json:"nodeId"` - Ip net.IP `json:"ip"` + Ip net.IP `json:"-"` P2pPort enr.TCP `json:"p2pPort"` RaftPort enr.RaftPort `json:"raftPort"` + + Hostname string `json:"hostname"` + + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `json:"-" rlp:"tail"` +} + +type ClusterInfo struct { + Address + Role string `json:"role"` } -func newAddress(raftId uint16, raftPort int, node *enode.Node) *Address { +func newAddress(raftId uint16, raftPort int, node *enode.Node, withHostname bool) *Address { // derive 64 byte nodeID from 128 byte enodeID id, err := enode.RaftHexID(node.EnodeID()) if err != nil { panic(err) } + if withHostname { + return &Address{ + RaftId: raftId, + NodeId: id, + Ip: nil, + P2pPort: enr.TCP(node.TCP()), + RaftPort: enr.RaftPort(raftPort), + Hostname: node.Host(), + } + } return &Address{ RaftId: raftId, NodeId: id, - Ip: node.IP(), + Ip: nil, P2pPort: enr.TCP(node.TCP()), RaftPort: enr.RaftPort(raftPort), + Hostname: node.IP().String(), } } @@ -43,12 +64,32 @@ type Peer struct { p2pNode *enode.Node // For ethereum transport } -func (addr *Address) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{addr.RaftId, addr.NodeId, addr.Ip, addr.P2pPort, addr.RaftPort}) +// RLP Address encoding, for transport over raft and storage in LevelDB. +func (addr *Address) toBytes(withHostname bool) []byte { + var toEncode interface{} + + if withHostname { + toEncode = addr + } else { + toEncode = []interface{}{addr.RaftId, addr.NodeId, net.ParseIP(addr.Hostname), addr.P2pPort, addr.RaftPort} + } + + buffer, err := rlp.EncodeToBytes(toEncode) + if err != nil { + panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error())) + } + return buffer } -func (addr *Address) DecodeRLP(s *rlp.Stream) error { - // These fields need to be public: +func bytesToAddress(input []byte) *Address { + //try the new format first + addr := new(Address) + streamNew := rlp.NewStream(bytes.NewReader(input), 0) + if err := streamNew.Decode(addr); err == nil { + return addr + } + + //else try the old format var temp struct { RaftId uint16 NodeId enode.EnodeID @@ -57,31 +98,17 @@ func (addr *Address) DecodeRLP(s *rlp.Stream) error { RaftPort enr.RaftPort } - if err := s.Decode(&temp); err != nil { - return err - } else { - addr.RaftId, addr.NodeId, addr.Ip, addr.P2pPort, addr.RaftPort = temp.RaftId, temp.NodeId, temp.Ip, temp.P2pPort, temp.RaftPort - return nil - } -} - -// RLP Address encoding, for transport over raft and storage in LevelDB. - -func (addr *Address) toBytes() []byte { - size, r, err := rlp.EncodeToReader(addr) - if err != nil { - panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error())) + streamOld := rlp.NewStream(bytes.NewReader(input), 0) + if err := streamOld.Decode(&temp); err != nil { + log.Fatalf("failed to RLP-decode Address: %v", err) } - var buffer = make([]byte, uint32(size)) - r.Read(buffer) - - return buffer -} -func bytesToAddress(bytes []byte) *Address { - var addr Address - if err := rlp.DecodeBytes(bytes, &addr); err != nil { - log.Fatalf("failed to RLP-decode Address: %v", err) + return &Address{ + RaftId: temp.RaftId, + NodeId: temp.NodeId, + Ip: nil, + P2pPort: temp.P2pPort, + RaftPort: temp.RaftPort, + Hostname: temp.Ip.String(), } - return &addr } diff --git a/raft/snapshot.go b/raft/snapshot.go index 7536453e23..30dc5a2a2d 100644 --- a/raft/snapshot.go +++ b/raft/snapshot.go @@ -1,29 +1,46 @@ package raft import ( + "bytes" "fmt" "io" "math/big" + "net" "sort" "time" "github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/snap" "github.com/coreos/etcd/wal/walpb" - "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" ) -// Snapshot +type SnapshotWithHostnames struct { + Addresses []Address + RemovedRaftIds []uint16 + HeadBlockHash common.Hash +} + +type AddressWithoutHostname struct { + RaftId uint16 + NodeId enode.EnodeID + Ip net.IP + P2pPort enr.TCP + RaftPort enr.RaftPort +} -type Snapshot struct { - addresses []Address - removedRaftIds []uint16 // Raft IDs for permanently removed peers - headBlockHash common.Hash +type SnapshotWithoutHostnames struct { + Addresses []AddressWithoutHostname + RemovedRaftIds []uint16 // Raft IDs for permanently removed peers + HeadBlockHash common.Hash } type ByRaftId []Address @@ -32,39 +49,38 @@ func (a ByRaftId) Len() int { return len(a) } func (a ByRaftId) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByRaftId) Less(i, j int) bool { return a[i].RaftId < a[j].RaftId } -func (pm *ProtocolManager) buildSnapshot() *Snapshot { +func (pm *ProtocolManager) buildSnapshot() *SnapshotWithHostnames { pm.mu.RLock() defer pm.mu.RUnlock() - numNodes := len(pm.confState.Nodes) + numNodes := len(pm.confState.Nodes) + len(pm.confState.Learners) numRemovedNodes := pm.removedPeers.Cardinality() - snapshot := &Snapshot{ - addresses: make([]Address, numNodes), - removedRaftIds: make([]uint16, numRemovedNodes), - headBlockHash: pm.blockchain.CurrentBlock().Hash(), + snapshot := &SnapshotWithHostnames{ + Addresses: make([]Address, numNodes), + RemovedRaftIds: make([]uint16, numRemovedNodes), + HeadBlockHash: pm.blockchain.CurrentBlock().Hash(), } // Populate addresses - for i, rawRaftId := range pm.confState.Nodes { + for i, rawRaftId := range append(pm.confState.Nodes, pm.confState.Learners...) { raftId := uint16(rawRaftId) if raftId == pm.raftId { - snapshot.addresses[i] = *pm.address + snapshot.Addresses[i] = *pm.address } else { - snapshot.addresses[i] = *pm.peers[raftId].address + snapshot.Addresses[i] = *pm.peers[raftId].address } } - sort.Sort(ByRaftId(snapshot.addresses)) + sort.Sort(ByRaftId(snapshot.Addresses)) // Populate removed IDs i := 0 for removedIface := range pm.removedPeers.Iterator().C { - snapshot.removedRaftIds[i] = removedIface.(uint16) + snapshot.RemovedRaftIds[i] = removedIface.(uint16) i++ } - return snapshot } @@ -81,7 +97,7 @@ func (pm *ProtocolManager) triggerSnapshot(index uint64) { //snapData := pm.blockchain.CurrentBlock().Hash().Bytes() //snap, err := pm.raftStorage.CreateSnapshot(pm.appliedIndex, &pm.confState, snapData) - snapData := pm.buildSnapshot().toBytes() + snapData := pm.buildSnapshot().toBytes(pm.useDns) snap, err := pm.raftStorage.CreateSnapshot(index, &pm.confState, snapData) if err != nil { panic(err) @@ -102,7 +118,7 @@ func (pm *ProtocolManager) triggerSnapshot(index uint64) { func confStateIdSet(confState raftpb.ConfState) mapset.Set { set := mapset.NewSet() - for _, rawRaftId := range confState.Nodes { + for _, rawRaftId := range append(confState.Nodes, confState.Learners...) { set.Add(uint16(rawRaftId)) } return set @@ -180,7 +196,6 @@ func (pm *ProtocolManager) maybeTriggerSnapshot() { func (pm *ProtocolManager) loadSnapshot() *raftpb.Snapshot { if raftSnapshot := pm.readRaftSnapshot(); raftSnapshot != nil { log.Info("loading snapshot") - pm.applyRaftSnapshot(*raftSnapshot) return raftSnapshot @@ -191,43 +206,74 @@ func (pm *ProtocolManager) loadSnapshot() *raftpb.Snapshot { } } -func (snapshot *Snapshot) toBytes() []byte { - size, r, err := rlp.EncodeToReader(snapshot) +func (snapshot *SnapshotWithHostnames) toBytes(useDns bool) []byte { + // we have DNS enabled, so only use the new snapshot type + if useDns { + buffer, err := rlp.EncodeToBytes(snapshot) + if err != nil { + panic(fmt.Sprintf("error: failed to RLP-encode Snapshot: %s", err.Error())) + } + return buffer + } + + // DNS is not enabled, use the old snapshot type, converting from hostnames to IP addresses + oldSnapshot := new(SnapshotWithoutHostnames) + oldSnapshot.HeadBlockHash, oldSnapshot.RemovedRaftIds = snapshot.HeadBlockHash, snapshot.RemovedRaftIds + oldSnapshot.Addresses = make([]AddressWithoutHostname, len(snapshot.Addresses)) + + for index, addrWithHost := range snapshot.Addresses { + oldSnapshot.Addresses[index] = AddressWithoutHostname{ + addrWithHost.RaftId, + addrWithHost.NodeId, + net.ParseIP(addrWithHost.Hostname), + addrWithHost.P2pPort, + addrWithHost.RaftPort, + } + } + + buffer, err := rlp.EncodeToBytes(oldSnapshot) if err != nil { panic(fmt.Sprintf("error: failed to RLP-encode Snapshot: %s", err.Error())) } - var buffer = make([]byte, uint32(size)) - r.Read(buffer) - return buffer } -func bytesToSnapshot(bytes []byte) *Snapshot { - var snapshot Snapshot - if err := rlp.DecodeBytes(bytes, &snapshot); err != nil { - fatalf("failed to RLP-decode Snapshot: %v", err) +func bytesToSnapshot(input []byte) *SnapshotWithHostnames { + var err, errOld error + + snapshot := new(SnapshotWithHostnames) + streamNewSnapshot := rlp.NewStream(bytes.NewReader(input), 0) + if err = streamNewSnapshot.Decode(snapshot); err == nil { + return snapshot } - return &snapshot -} -func (snapshot *Snapshot) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{snapshot.addresses, snapshot.removedRaftIds, snapshot.headBlockHash}) -} + snapshotOld := new(SnapshotWithoutHostnames) + streamOldSnapshot := rlp.NewStream(bytes.NewReader(input), 0) + if errOld = streamOldSnapshot.Decode(snapshotOld); errOld == nil { + var snapshotConverted SnapshotWithHostnames + snapshotConverted.RemovedRaftIds, snapshotConverted.HeadBlockHash = snapshotOld.RemovedRaftIds, snapshotOld.HeadBlockHash + snapshotConverted.Addresses = make([]Address, len(snapshotOld.Addresses)) + + for index, oldAddrWithIp := range snapshotOld.Addresses { + snapshotConverted.Addresses[index] = Address{ + RaftId: oldAddrWithIp.RaftId, + NodeId: oldAddrWithIp.NodeId, + Ip: nil, + P2pPort: oldAddrWithIp.P2pPort, + RaftPort: oldAddrWithIp.RaftPort, + Hostname: oldAddrWithIp.Ip.String(), + } + } -func (snapshot *Snapshot) DecodeRLP(s *rlp.Stream) error { - // These fields need to be public: - var temp struct { - Addresses []Address - RemovedRaftIds []uint16 - HeadBlockHash common.Hash + return &snapshotConverted } - if err := s.Decode(&temp); err != nil { - return err - } else { - snapshot.addresses, snapshot.removedRaftIds, snapshot.headBlockHash = temp.Addresses, temp.RemovedRaftIds, temp.HeadBlockHash - return nil - } + fatalf("failed to RLP-decode Snapshot: %v, %v", err, errOld) + return nil +} + +func (snapshot *SnapshotWithHostnames) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{snapshot.Addresses, snapshot.RemovedRaftIds, snapshot.HeadBlockHash}) } // Raft snapshot @@ -265,9 +311,9 @@ func (pm *ProtocolManager) applyRaftSnapshot(raftSnapshot raftpb.Snapshot) { } snapshot := bytesToSnapshot(raftSnapshot.Data) - latestBlockHash := snapshot.headBlockHash + latestBlockHash := snapshot.HeadBlockHash - pm.updateClusterMembership(raftSnapshot.Metadata.ConfState, snapshot.addresses, snapshot.removedRaftIds) + pm.updateClusterMembership(raftSnapshot.Metadata.ConfState, snapshot.Addresses, snapshot.RemovedRaftIds) preSyncHead := pm.blockchain.CurrentBlock() @@ -277,6 +323,8 @@ func (pm *ProtocolManager) applyRaftSnapshot(raftSnapshot raftpb.Snapshot) { log.Info(chainExtensionMessage, "hash", pm.blockchain.CurrentBlock().Hash()) } else { + // added for permissions changes to indicate node sync up has started + types.SetSyncStatus() log.Info("blockchain is caught up; no need to synchronize") } diff --git a/raft/speculative_chain.go b/raft/speculative_chain.go index 5dcb826584..3fa8806cc8 100644 --- a/raft/speculative_chain.go +++ b/raft/speculative_chain.go @@ -1,12 +1,12 @@ package raft import ( + mapset "github.com/deckarep/golang-set" + "gopkg.in/oleiade/lane.v1" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" - - "github.com/deckarep/golang-set" - "gopkg.in/oleiade/lane.v1" ) // The speculative chain represents blocks that we have minted which haven't been accepted into the chain yet, building diff --git a/raft/wal.go b/raft/wal.go index f423fa6883..ca04d99472 100644 --- a/raft/wal.go +++ b/raft/wal.go @@ -38,7 +38,7 @@ func (pm *ProtocolManager) openWAL(maybeRaftSnapshot *raftpb.Snapshot) *wal.WAL return wal } -func (pm *ProtocolManager) replayWAL(maybeRaftSnapshot *raftpb.Snapshot) *wal.WAL { +func (pm *ProtocolManager) replayWAL(maybeRaftSnapshot *raftpb.Snapshot) (*wal.WAL, []raftpb.Entry) { log.Info("replaying WAL") wal := pm.openWAL(maybeRaftSnapshot) @@ -50,5 +50,5 @@ func (pm *ProtocolManager) replayWAL(maybeRaftSnapshot *raftpb.Snapshot) *wal.WA pm.raftStorage.SetHardState(hardState) pm.raftStorage.Append(entries) - return wal + return wal, entries } diff --git a/rpc/http.go b/rpc/http.go index af79858e2b..500fb0e906 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -37,7 +37,7 @@ import ( const ( contentType = "application/json" - maxRequestContentLength = 1024 * 512 + maxRequestContentLength = 1024 * 1024 * 5 ) var nullAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:0") diff --git a/rpc/inproc.go b/rpc/inproc.go index cbe65d10e7..f508d29bbc 100644 --- a/rpc/inproc.go +++ b/rpc/inproc.go @@ -21,6 +21,10 @@ import ( "net" ) +type InProcServerReadyEvent struct { + +} + // DialInProc attaches an in-process connection to the given RPC server. func DialInProc(handler *Server) *Client { initctx := context.Background() diff --git a/rpc/server.go b/rpc/server.go index 5d8b7329c4..bd5f71d221 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -127,7 +127,7 @@ func (s *Server) serveRequest(ctx context.Context, codec ServerCodec, singleShot defer func() { if err := recover(); err != nil { - const size = 64 << 10 + const size = 128 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] log.Error(string(buf)) diff --git a/trie/database.go b/trie/database.go index d0691b637e..d819de1f92 100644 --- a/trie/database.go +++ b/trie/database.go @@ -134,7 +134,7 @@ type cachedNode struct { node node // Cached collapsed trie node, or raw rlp data size uint16 // Byte size of the useful cached data - parents uint16 // Number of live nodes referencing this one + parents uint32 // Number of live nodes referencing this one children map[common.Hash]uint16 // External children referenced by this node flushPrev common.Hash // Previous node in the flush-list diff --git a/vendor/github.com/coreos/etcd/.gitignore b/vendor/github.com/coreos/etcd/.gitignore index 604fd4d27d..b055a98538 100644 --- a/vendor/github.com/coreos/etcd/.gitignore +++ b/vendor/github.com/coreos/etcd/.gitignore @@ -1,14 +1,21 @@ +/agent-* /coverage +/covdir +/docs +/vendor /gopath /gopath.proto /go-bindata +/release /machine* /bin .vagrant *.etcd +*.log /etcd *.swp /hack/insta-discovery/.env *.test -tools/functional-tester/docker/bin hack/tls-setup/certs +.idea +*.bak diff --git a/vendor/github.com/coreos/etcd/.travis.yml b/vendor/github.com/coreos/etcd/.travis.yml index 40a65e0e52..8ff5ff08fc 100644 --- a/vendor/github.com/coreos/etcd/.travis.yml +++ b/vendor/github.com/coreos/etcd/.travis.yml @@ -1,61 +1,73 @@ -dist: trusty language: go go_import_path: github.com/coreos/etcd -sudo: false + +sudo: required + +services: docker go: - - 1.7.4 - - tip +- 1.10.8 + +notifications: + on_success: never + on_failure: never env: matrix: - - TARGET=amd64 - - TARGET=arm64 - - TARGET=arm - - TARGET=386 - - TARGET=ppc64le + - TARGET=linux-amd64-integration + - TARGET=linux-amd64-functional + - TARGET=linux-amd64-unit + - TARGET=all-build + - TARGET=linux-386-unit matrix: fast_finish: true allow_failures: - - go: tip + - go: 1.10.8 + env: TARGET=linux-386-unit exclude: - go: tip - env: TARGET=arm - - go: tip - env: TARGET=arm64 - - go: tip - env: TARGET=386 - - go: tip - env: TARGET=ppc64le - -addons: - apt: - packages: - - libpcap-dev - - libaspell-dev - - libhunspell-dev + env: TARGET=linux-386-unit before_install: - - go get -v github.com/chzchzchz/goword - - go get -v honnef.co/go/simple/cmd/gosimple - - go get -v honnef.co/go/unused/cmd/unused +- if [[ $TRAVIS_GO_VERSION == 1.* ]]; then docker pull gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION}; fi -# disable godep restore override install: - - pushd cmd/etcd && go get -t -v ./... && popd +- pushd cmd/etcd && go get -t -v ./... && popd script: + - echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}" - > case "${TARGET}" in - amd64) - GOARCH=amd64 ./test + linux-amd64-integration) + docker run --rm \ + --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ + /bin/bash -c "cd /go/src/github.com/coreos/etcd; GOARCH=amd64 PASSES='integration' ./test" + ;; + linux-amd64-functional) + docker run --rm \ + --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ + /bin/bash -c "cd /go/src/github.com/coreos/etcd; ./build && GOARCH=amd64 PASSES='functional' ./test" + ;; + linux-amd64-unit) + docker run --rm \ + --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ + /bin/bash -c "cd /go/src/github.com/coreos/etcd; GOARCH=amd64 PASSES='unit' ./test" ;; - 386) - GOARCH=386 PASSES="build unit" ./test + all-build) + docker run --rm \ + --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ + /bin/bash -c "cd /go/src/github.com/coreos/etcd; GOARCH=amd64 PASSES='build' ./test \ + && GOARCH=386 PASSES='build' ./test \ + && GO_BUILD_FLAGS='-v' GOOS=darwin GOARCH=amd64 ./build \ + && GO_BUILD_FLAGS='-v' GOOS=windows GOARCH=amd64 ./build \ + && GO_BUILD_FLAGS='-v' GOARCH=arm ./build \ + && GO_BUILD_FLAGS='-v' GOARCH=arm64 ./build \ + && GO_BUILD_FLAGS='-v' GOARCH=ppc64le ./build" ;; - *) - # test building out of gopath - GO_BUILD_FLAGS="-a -v" GOPATH="" GOARCH="${TARGET}" ./build + linux-386-unit) + docker run --rm \ + --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \ + /bin/bash -c "cd /go/src/github.com/coreos/etcd; GOARCH=386 PASSES='unit' ./test" ;; esac diff --git a/vendor/github.com/coreos/etcd/.words b/vendor/github.com/coreos/etcd/.words new file mode 100644 index 0000000000..31fffef38f --- /dev/null +++ b/vendor/github.com/coreos/etcd/.words @@ -0,0 +1,44 @@ +DefaultMaxRequestBytes +ErrCodeEnhanceYourCalm +ErrTimeout +GoAway +KeepAlive +Keepalive +MiB +ResourceExhausted +RPC +RPCs +TODO +backoff +blackhole +blackholed +cancelable +cancelation +cluster_proxy +defragment +defragmenting +etcd +gRPC +goroutine +goroutines +healthcheck +iff +inflight +keepalive +keepalives +keyspace +linearization +localhost +mutex +prefetching +protobuf +prometheus +rafthttp +repin +serializable +teardown +too_many_pings +uncontended +unprefixed +unlisting + diff --git a/vendor/github.com/coreos/etcd/CHANGELOG.md b/vendor/github.com/coreos/etcd/CHANGELOG.md new file mode 100644 index 0000000000..603e501d25 --- /dev/null +++ b/vendor/github.com/coreos/etcd/CHANGELOG.md @@ -0,0 +1,746 @@ +## [v3.3.0](https://github.com/coreos/etcd/releases/tag/v3.3.0) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.3.0) and [v3.3 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_3.md) for any breaking changes. + +### Improved + +- Use [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to replace [`boltdb/bolt`](https://github.com/boltdb/bolt#project-status). + - Fix [etcd database size grows until `mvcc: database space exceeded`](https://github.com/coreos/etcd/issues/8009). +- [Reduce memory allocation](https://github.com/coreos/etcd/pull/8428) on [Range operations](https://github.com/coreos/etcd/pull/8475). +- [Rate limit](https://github.com/coreos/etcd/pull/8099) and [randomize](https://github.com/coreos/etcd/pull/8101) lease revoke on restart or leader elections. + - Prevent [spikes in Raft proposal rate](https://github.com/coreos/etcd/issues/8096). +- Support `clientv3` balancer failover under [network faults/partitions](https://github.com/coreos/etcd/issues/8711). +- Better warning on [mismatched `--initial-cluster`](https://github.com/coreos/etcd/pull/8083) flag. + +### Changed(Breaking Changes) + +- Require [Go 1.9+](https://github.com/coreos/etcd/issues/6174). + - Compile with *Go 1.9.2*. + - Deprecate [`golang.org/x/net/context`](https://github.com/coreos/etcd/pull/8511). +- Require [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) [**`v1.7.4`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.4) or [**`v1.7.5+`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.5): + - Deprecate [`metadata.Incoming/OutgoingContext`](https://github.com/coreos/etcd/pull/7896). + - Deprecate `grpclog.Logger`, upgrade to [`grpclog.LoggerV2`](https://github.com/coreos/etcd/pull/8533). + - Deprecate [`grpc.ErrClientConnTimeout`](https://github.com/coreos/etcd/pull/8505) errors in `clientv3`. + - Use [`MaxRecvMsgSize` and `MaxSendMsgSize`](https://github.com/coreos/etcd/pull/8437) to limit message size, in etcd server. +- Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2.2` to `v1.3.0`. +- Translate [gRPC status error in v3 client `Snapshot` API](https://github.com/coreos/etcd/pull/9038). +- Upgrade [`github.com/ugorji/go/codec`](https://github.com/ugorji/go) for v2 `client`. + - [Regenerated](https://github.com/coreos/etcd/pull/8721) v2 `client` source code with latest `ugorji/go/codec`. +- Fix [`/health` endpoint JSON output](https://github.com/coreos/etcd/pull/8312). +- v3 `etcdctl` [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease now prints [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047). + - <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`. + +### Added(`etcd`) + +- Add [`--experimental-enable-v2v3`](https://github.com/coreos/etcd/pull/8407) flag to [emulate v2 API with v3](https://github.com/coreos/etcd/issues/6925). +- Add [`--experimental-corrupt-check-time`](https://github.com/coreos/etcd/pull/8420) flag to [raise corrupt alarm monitoring](https://github.com/coreos/etcd/issues/7125). +- Add [`--experimental-initial-corrupt-check`](https://github.com/coreos/etcd/pull/8554) flag to [check database hash before serving client/peer traffic](https://github.com/coreos/etcd/issues/8313). +- Add [`--max-txn-ops`](https://github.com/coreos/etcd/pull/7976) flag to [configure maximum number operations in transaction](https://github.com/coreos/etcd/issues/7826). +- Add [`--max-request-bytes`](https://github.com/coreos/etcd/pull/7968) flag to [configure maximum client request size](https://github.com/coreos/etcd/issues/7923). + - If not configured, it defaults to 1.5 MiB. +- Add [`--client-crl-file`, `--peer-crl-file`](https://github.com/coreos/etcd/pull/8124) flags for [Certificate revocation list](https://github.com/coreos/etcd/issues/4034). +- Add [`--peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag to support [CN-based auth for inter-peer connection](https://github.com/coreos/etcd/issues/8262). +- Add [`--listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints. + - Support [additional (non) TLS `/metrics` endpoints for a TLS-enabled cluster](https://github.com/coreos/etcd/pull/8282). + - e.g. `--listen-metrics-urls=https://localhost:2378,http://localhost:9379` to serve `/metrics` in secure port 2378 and insecure port 9379. + - Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060). +- Add [`--auto-compaction-mode`](https://github.com/coreos/etcd/pull/8123) flag to [support revision-based compaction](https://github.com/coreos/etcd/issues/8098). +- Change `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503). +- Add [`--grpc-keepalive-min-time`, `--grpc-keepalive-interval`, `--grpc-keepalive-timeout`](https://github.com/coreos/etcd/pull/8535) flags to configure server-side keepalive policies. +- Serve [`/health` endpoint as unhealthy](https://github.com/coreos/etcd/pull/8272) when [alarm is raised](https://github.com/coreos/etcd/issues/8207). +- Provide [error information in `/health`](https://github.com/coreos/etcd/pull/8312). + - e.g. `{"health":false,"errors":["NOSPACE"]}`. +- Move [logging setup to embed package](https://github.com/coreos/etcd/pull/8810) + - Disable gRPC server log by default. +- Use [monotonic time in Go 1.9](https://github.com/coreos/etcd/pull/8507) for `lease` package. +- Warn on [empty hosts in advertise URLs](https://github.com/coreos/etcd/pull/8384). + - Address [advertise client URLs accepts empty hosts](https://github.com/coreos/etcd/issues/8379). + - etcd `v3.4` will exit on this error. + - e.g. `--advertise-client-urls=http://:2379`. +- Warn on [shadowed environment variables](https://github.com/coreos/etcd/pull/8385). + - Address [error on shadowed environment variables](https://github.com/coreos/etcd/issues/8380). + - etcd `v3.4` will exit on this error. + +### Added(API) + +- Support [ranges in transaction comparisons](https://github.com/coreos/etcd/pull/8025) for [disconnected linearized reads](https://github.com/coreos/etcd/issues/7924). +- Add [nested transactions](https://github.com/coreos/etcd/pull/8102) to extend [proxy use cases](https://github.com/coreos/etcd/issues/7857). +- Add [lease comparison target in transaction](https://github.com/coreos/etcd/pull/8324). +- Add [lease list](https://github.com/coreos/etcd/pull/8358). +- Add [hash by revision](https://github.com/coreos/etcd/pull/8263) for [better corruption checking against boltdb](https://github.com/coreos/etcd/issues/8016). + +### Added(`etcd/clientv3`) + +- Add [health balancer](https://github.com/coreos/etcd/pull/8545) to fix [watch API hangs](https://github.com/coreos/etcd/issues/7247), improve [endpoint switch under network faults](https://github.com/coreos/etcd/issues/7941). +- [Refactor balancer](https://github.com/coreos/etcd/pull/8840) and add [client-side keepalive pings](https://github.com/coreos/etcd/pull/8199) to handle [network partitions](https://github.com/coreos/etcd/issues/8711). +- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config). + - Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043). + - Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099). + - `MaxCallSendMsgSize` default value is 2 MiB, if not configured. + - `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured. +- Accept [`Compare_LEASE`](https://github.com/coreos/etcd/pull/8324) in [`clientv3.Compare`](https://godoc.org/github.com/coreos/etcd/clientv3#Compare). +- Add [`LeaseValue` helper](https://github.com/coreos/etcd/pull/8488) to `Cmp` `LeaseID` values in `Txn`. +- Add [`MoveLeader`](https://github.com/coreos/etcd/pull/8153) to `Maintenance`. +- Add [`HashKV`](https://github.com/coreos/etcd/pull/8351) to `Maintenance`. +- Add [`Leases`](https://github.com/coreos/etcd/pull/8358) to `Lease`. +- Add [`clientv3/ordering`](https://github.com/coreos/etcd/pull/8092) for enforce [ordering in serialized requests](https://github.com/coreos/etcd/issues/7623). + +### Added(v2 `etcdctl`) + +- Add [`backup --with-v3`](https://github.com/coreos/etcd/pull/8479) flag. + +### Added(v3 `etcdctl`) + +- Add [`--discovery-srv`](https://github.com/coreos/etcd/pull/8462) flag. +- Add [`--keepalive-time`, `--keepalive-timeout`](https://github.com/coreos/etcd/pull/8663) flags. +- Add [`lease list`](https://github.com/coreos/etcd/pull/8358) command. +- Add [`lease keep-alive --once`](https://github.com/coreos/etcd/pull/8775) flag. +- Make [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease print [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047). + - <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`. +- Add [`defrag --data-dir`](https://github.com/coreos/etcd/pull/8367) flag. +- Add [`move-leader`](https://github.com/coreos/etcd/pull/8153) command. +- Add [`endpoint hashkv`](https://github.com/coreos/etcd/pull/8351) command. +- Add [`endpoint --cluster`](https://github.com/coreos/etcd/pull/8143) flag, equivalent to [v2 `etcdctl cluster-health`](https://github.com/coreos/etcd/issues/8117). +- Make `endpoint health` command terminate with [non-zero exit code on unhealthy status](https://github.com/coreos/etcd/pull/8342). +- Add [`lock --ttl`](https://github.com/coreos/etcd/pull/8370) flag. +- Support [`watch [key] [range_end] -- [exec-command…]`](https://github.com/coreos/etcd/pull/8919), equivalent to [v2 `etcdctl exec-watch`](https://github.com/coreos/etcd/issues/8814). +- Enable [`clientv3.WithRequireLeader(context.Context)` for `watch`](https://github.com/coreos/etcd/pull/8672) command. +- Print [`"del"` instead of `"delete"`](https://github.com/coreos/etcd/pull/8297) in `txn` interactive mode. +- Print [`ETCD_INITIAL_ADVERTISE_PEER_URLS` in `member add`](https://github.com/coreos/etcd/pull/8332). + +### Added(metrics) + +- Add [`etcd --listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints. + - Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060). +- Add [`etcd_server_version`](https://github.com/coreos/etcd/pull/8960) Prometheus metric. + - To replace [Kubernetes `etcd-version-monitor`](https://github.com/coreos/etcd/issues/8948). +- Add [`etcd_debugging_mvcc_db_compaction_keys_total`](https://github.com/coreos/etcd/pull/8280) Prometheus metric. +- Add [`etcd_debugging_server_lease_expired_total`](https://github.com/coreos/etcd/pull/8064) Prometheus metric. + - To improve [lease revoke monitoring](https://github.com/coreos/etcd/issues/8050). +- Document [Prometheus 2.0 rules](https://github.com/coreos/etcd/pull/8879). +- Initialize gRPC server [metrics with zero values](https://github.com/coreos/etcd/pull/8878). + +### Added(`grpc-proxy`) + +- Add [`grpc-proxy start --experimental-leasing-prefix`](https://github.com/coreos/etcd/pull/8341) flag: + - For disconnected linearized reads. + - Based on [V system leasing](https://github.com/coreos/etcd/issues/6065). + - See ["Disconnected consistent reads with etcd" blog post](https://coreos.com/blog/coreos-labs-disconnected-consistent-reads-with-etcd). +- Add [`grpc-proxy start --experimental-serializable-ordering`](https://github.com/coreos/etcd/pull/8315) flag. + - To ensure serializable reads have monotonically increasing store revisions across endpoints. +- Add [`grpc-proxy start --metrics-addr`](https://github.com/coreos/etcd/pull/8242) flag for an additional `/metrics` endpoint. + - Set `--metrics-addr=http://[HOST]:9379` to serve `/metrics` in insecure port 9379. +- Serve [`/health` endpoint in grpc-proxy](https://github.com/coreos/etcd/pull/8322). +- Add [`grpc-proxy start --debug`](https://github.com/coreos/etcd/pull/8994) flag. + +### Added(gRPC gateway) + +- Replace [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) endpoint with [`/v3beta`](https://github.com/coreos/etcd/pull/8880). + - To deprecate [`/v3alpha`](https://github.com/coreos/etcd/issues/8125) in `v3.4`. +- Support ["authorization" token](https://github.com/coreos/etcd/pull/7999). +- Support [websocket for bi-directional streams](https://github.com/coreos/etcd/pull/8257). + - Fix [`Watch` API with gRPC gateway](https://github.com/coreos/etcd/issues/8237). +- Upgrade gRPC gateway to [v1.3.0](https://github.com/coreos/etcd/issues/8838). + +### Added(`etcd/raft`) + +- Add [non-voting member](https://github.com/coreos/etcd/pull/8751). + - To implement [Raft thesis 4.2.1 Catching up new servers](https://github.com/coreos/etcd/issues/8568). + - `Learner` node does not vote or promote itself. + +### Added/Fixed(Security/Auth) + +- Add [CRL based connection rejection](https://github.com/coreos/etcd/pull/8124) to manage [revoked certs](https://github.com/coreos/etcd/issues/4034). +- Document [TLS authentication changes](https://github.com/coreos/etcd/pull/8895): + - [Server accepts connections if IP matches, without checking DNS entries](https://github.com/coreos/etcd/pull/8223). For instance, if peer cert contains IP addresses and DNS names in Subject Alternative Name (SAN) field, and the remote IP address matches one of those IP addresses, server just accepts connection without further checking the DNS names. + - [Server supports reverse-lookup on wildcard DNS `SAN`](https://github.com/coreos/etcd/pull/8281). For instance, if peer cert contains only DNS names (no IP addresses) in Subject Alternative Name (SAN) field, server first reverse-lookups the remote IP address to get a list of names mapping to that address (e.g. `nslookup IPADDR`). Then accepts the connection if those names have a matching name with peer cert's DNS names (either by exact or wildcard match). If none is matched, server forward-lookups each DNS entry in peer cert (e.g. look up `example.default.svc` when the entry is `*.example.default.svc`), and accepts connection only when the host's resolved addresses have the matching IP address with the peer's remote IP address. +- Add [`etcd --peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag. + - To support [CommonName(CN) based auth](https://github.com/coreos/etcd/issues/8262) for inter peer connection. +- [Swap priority](https://github.com/coreos/etcd/pull/8594) of cert CommonName(CN) and username + password. + - To address ["username and password specified in the request should take priority over CN in the cert"](https://github.com/coreos/etcd/issues/8584). +- Protect [lease revoke with auth](https://github.com/coreos/etcd/pull/8031). +- Provide user's role on [auth permission error](https://github.com/coreos/etcd/pull/8164). +- Fix [auth store panic with disabled token](https://github.com/coreos/etcd/pull/8695). +- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)). + +### Fixed(v2) + +- [Fail-over v2 client](https://github.com/coreos/etcd/pull/8519) to next endpoint on [oneshot failure](https://github.com/coreos/etcd/issues/8515). +- [Put back `/v2/machines`](https://github.com/coreos/etcd/pull/8062) endpoint for python-etcd wrapper. + +### Fixed(v3) + +- Fix [range/put/delete operation metrics](https://github.com/coreos/etcd/pull/8054) with transaction: + - `etcd_debugging_mvcc_range_total` + - `etcd_debugging_mvcc_put_total` + - `etcd_debugging_mvcc_delete_total` + - `etcd_debugging_mvcc_txn_total` +- Fix [`etcd_debugging_mvcc_keys_total`](https://github.com/coreos/etcd/pull/8390) on restore. +- Fix [`etcd_debugging_mvcc_db_total_size_in_bytes`](https://github.com/coreos/etcd/pull/8120) on restore. + - Also change to [`prometheus.NewGaugeFunc`](https://github.com/coreos/etcd/pull/8150). +- Fix [backend database in-memory index corruption](https://github.com/coreos/etcd/pull/8127) issue on restore (only 3.2.0 is affected). +- Fix [watch restore from snapshot](https://github.com/coreos/etcd/pull/8427). +- Fix ["put at-most-once" in `clientv3`](https://github.com/coreos/etcd/pull/8335). +- Handle [empty key permission](https://github.com/coreos/etcd/pull/8514) in `etcdctl`. +- [Fix server crash](https://github.com/coreos/etcd/pull/8010) on [invalid transaction request from gRPC gateway](https://github.com/coreos/etcd/issues/7889). +- Fix [`clientv3.WatchResponse.Canceled`](https://github.com/coreos/etcd/pull/8283) on [compacted watch request](https://github.com/coreos/etcd/issues/8231). +- Handle [WAL renaming failure on Windows](https://github.com/coreos/etcd/pull/8286). +- Make [peer dial timeout longer](https://github.com/coreos/etcd/pull/8599). + - See [coreos/etcd-operator#1300](https://github.com/coreos/etcd-operator/issues/1300) for more detail. +- Make server [wait up to request time-out](https://github.com/coreos/etcd/pull/8267) with [pending RPCs](https://github.com/coreos/etcd/issues/8224). +- Fix [`grpc.Server` panic on `GracefulStop`](https://github.com/coreos/etcd/pull/8987) with [TLS-enabled server](https://github.com/coreos/etcd/issues/8916). +- Fix ["multiple peer URLs cannot start" issue](https://github.com/coreos/etcd/issues/8383). +- Fix server-side auth so [concurrent auth operations do not return old revision error](https://github.com/coreos/etcd/pull/8442). +- Fix [`concurrency/stm` `Put` with serializable snapshot](https://github.com/coreos/etcd/pull/8439). + - Use store revision from first fetch to resolve write conflicts instead of modified revision. +- Fix [`grpc-proxy` Snapshot API error handling](https://github.com/coreos/etcd/commit/dbd16d52fbf81e5fd806d21ff5e9148d5bf203ab). +- Fix [`grpc-proxy` KV API `PrevKv` flag handling](https://github.com/coreos/etcd/pull/8366). +- Fix [`grpc-proxy` KV API `KeysOnly` flag handling](https://github.com/coreos/etcd/pull/8552). +- Upgrade [`coreos/go-systemd`](https://github.com/coreos/go-systemd/releases) to `v15` (see https://github.com/coreos/go-systemd/releases/tag/v15). + +### Other + +- Support previous two minor versions (see our [new release policy](https://github.com/coreos/etcd/pull/8805)). +- `v3.3.x` is the last release cycle that supports `ACI`: + - AppC was [officially suspended](https://github.com/appc/spec#-disclaimer-), as of late 2016. + - [`acbuild`](https://github.com/containers/build#this-project-is-currently-unmaintained) is not maintained anymore. + - `*.aci` files won't be available from etcd `v3.4` release. +- Add container registry [`gcr.io/etcd-development/etcd`](https://gcr.io/etcd-development/etcd). + - [quay.io/coreos/etcd](https://quay.io/coreos/etcd) is still supported as secondary. + + +## [v3.2.12](https://github.com/coreos/etcd/releases/tag/v3.2.12) (2017-12-20) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.11...v3.2.12) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Fix [error message of `Revision` compactor](https://github.com/coreos/etcd/pull/8999) in server-side. + +### Added(`etcd/clientv3`,`etcdctl/v3`) + +- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config). + - Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043). + - Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099). + - `MaxCallSendMsgSize` default value is 2 MiB, if not configured. + - `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured. + +### Other + +- Pin [grpc v1.7.5](https://github.com/grpc/grpc-go/releases/tag/v1.7.5), [grpc-gateway v1.3.0](https://github.com/grpc-ecosystem/grpc-gateway/releases/tag/v1.3.0). + - No code change, just to be explicit about recommended versions. + + +## [v3.2.11](https://github.com/coreos/etcd/releases/tag/v3.2.11) (2017-12-05) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.10...v3.2.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Fix racey grpc-go's server handler transport `WriteStatus` call to prevent [TLS-enabled etcd server crash](https://github.com/coreos/etcd/issues/8904): + - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.7.3` to `v1.7.4`. + - Add [gRPC RPC failure warnings](https://github.com/coreos/etcd/pull/8939) to help debug such issues in the future. +- Remove `--listen-metrics-urls` flag in monitoring document (non-released in `v3.2.x`, planned for `v3.3.x`). + +### Added + +- Provide [more cert details](https://github.com/coreos/etcd/pull/8952/files) on TLS handshake failures. + + +## [v3.1.11](https://github.com/coreos/etcd/releases/tag/v3.1.11) (2017-11-28) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.10...v3.1.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- [#8411](https://github.com/coreos/etcd/issues/8411),[#8806](https://github.com/coreos/etcd/pull/8806) mvcc: fix watch restore from snapshot +- [#8009](https://github.com/coreos/etcd/issues/8009),[#8902](https://github.com/coreos/etcd/pull/8902) backport coreos/bbolt v1.3.1-coreos.5 + + +## [v3.2.10](https://github.com/coreos/etcd/releases/tag/v3.2.10) (2017-11-16) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.9...v3.2.10) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Replace backend key-value database `boltdb/bolt` with [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to address [backend database size issue](https://github.com/coreos/etcd/issues/8009). +- Fix `clientv3` balancer to handle [network partitions](https://github.com/coreos/etcd/issues/8711): + - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.2.1` to `v1.7.3`. + - Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2` to `v1.3`. +- Revert [discovery SRV auth `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651) to support non-wildcard subject alternative names in the certs (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts). + - For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `etcd.local` (**not `*.etcd.local`**) as an entry in Subject Alternative Name (SAN) field. + + +## [v3.2.9](https://github.com/coreos/etcd/releases/tag/v3.2.9) (2017-10-06) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.8...v3.2.9) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed(Security) + +- Compile with [Go 1.8.4](https://groups.google.com/d/msg/golang-nuts/sHfMg4gZNps/a-HDgDDDAAAJ). +- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)). +- Fix discovery SRV bootstrapping to [authenticate `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651), in order to support sub-domain wildcard matching (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts). + - For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `*.etcd.local` as an entry in Subject Alternative Name (SAN) field. + + +## [v3.2.8](https://github.com/coreos/etcd/releases/tag/v3.2.8) (2017-09-29) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.7...v3.2.8) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Fix v2 client failover to next endpoint on mutable operation. +- Fix grpc-proxy to respect `KeysOnly` flag. + + +## [v3.2.7](https://github.com/coreos/etcd/releases/tag/v3.2.7) (2017-09-01) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.6...v3.2.7) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Fix server-side auth so concurrent auth operations do not return old revision error. +- Fix concurrency/stm Put with serializable snapshot + - Use store revision from first fetch to resolve write conflicts instead of modified revision. + + +## [v3.2.6](https://github.com/coreos/etcd/releases/tag/v3.2.6) (2017-08-21) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.5...v3.2.6). + +### Fixed + +- Fix watch restore from snapshot. +- Fix `etcd_debugging_mvcc_keys_total` inconsistency. +- Fix multiple URLs for `--listen-peer-urls` flag. +- Add `--enable-pprof` flag to etcd configuration file format. + + +## [v3.2.5](https://github.com/coreos/etcd/releases/tag/v3.2.5) (2017-08-04) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.4...v3.2.5) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Changed + +- Use reverse lookup to match wildcard DNS SAN. +- Return non-zero exit code on unhealthy `endpoint health`. + +### Fixed + +- Fix unreachable /metrics endpoint when `--enable-v2=false`. +- Fix grpc-proxy to respect `PrevKv` flag. + +### Added + +- Add container registry `gcr.io/etcd-development/etcd`. + + +## [v3.2.4](https://github.com/coreos/etcd/releases/tag/v3.2.4) (2017-07-19) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.3...v3.2.4) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Do not block on active client stream when stopping server +- Fix gRPC proxy Snapshot RPC error handling + + +## [v3.2.3](https://github.com/coreos/etcd/releases/tag/v3.2.3) (2017-07-14) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.2...v3.2.3) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Let clients establish unlimited streams + +### Added + +- Tag docker images with minor versions + - e.g. `docker pull quay.io/coreos/etcd:v3.2` to fetch latest v3.2 versions + + +## [v3.1.10](https://github.com/coreos/etcd/releases/tag/v3.1.10) (2017-07-14) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.9...v3.1.10) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Changed + +- Compile with Go 1.8.3 to fix panic on `net/http.CloseNotify` + +### Added + +- Tag docker images with minor versions. + - e.g. `docker pull quay.io/coreos/etcd:v3.1` to fetch latest v3.1 versions. + + +## [v3.2.2](https://github.com/coreos/etcd/releases/tag/v3.2.2) (2017-07-07) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.1...v3.2.2) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Improved + +- Rate-limit lease revoke on expiration. +- Extend leases on promote to avoid queueing effect on lease expiration. + +### Fixed + +- Use user-provided listen address to connect to gRPC gateway: + - `net.Listener` rewrites IPv4 0.0.0.0 to IPv6 [::], breaking IPv6 disabled hosts. + - Only v3.2.0, v3.2.1 are affected. +- Accept connection with matched IP SAN but no DNS match. + - Don't check DNS entries in certs if there's a matching IP. +- Fix 'tools/benchmark' watch command. + + +## [v3.2.1](https://github.com/coreos/etcd/releases/tag/v3.2.1) (2017-06-23) + +See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.2.1) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Fixed + +- Fix backend database in-memory index corruption issue on restore (only 3.2.0 is affected). +- Fix gRPC gateway Txn marshaling issue. +- Fix backend database size debugging metrics. + + +## [v3.2.0](https://github.com/coreos/etcd/releases/tag/v3.2.0) (2017-06-09) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.2.0) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. + +### Improved + +- Improve backend read concurrency. + +### Added + +- Embedded etcd + - `Etcd.Peers` field is now `[]*peerListener`. +- RPCs + - Add Election, Lock service. +- Native client etcdserver/api/v3client + - client "embedded" in the server. +- gRPC proxy + - Proxy endpoint discovery. + - Namespaces. + - Coalesce lease requests. +- v3 client + - STM prefetching. + - Add namespace feature. + - Add `ErrOldCluster` with server version checking. + - Translate `WithPrefix()` into `WithFromKey()` for empty key. +- v3 etcdctl + - Add `check perf` command. + - Add `--from-key` flag to role grant-permission command. + - `lock` command takes an optional command to execute. +- etcd flags + - Add `--enable-v2` flag to configure v2 backend (enabled by default). + - Add `--auth-token` flag. +- `etcd gateway` + - Support DNS SRV priority. +- Auth + - Support Watch API. + - JWT tokens. +- Logging, monitoring + - Server warns large snapshot operations. + - Add `etcd_debugging_server_lease_expired_total` metrics. +- Security + - Deny incoming peer certs with wrong IP SAN. + - Resolve TLS `DNSNames` when SAN checking. + - Reload TLS certificates on every client connection. +- Release + - Annotate acbuild with supports-systemd-notify. + - Add `nsswitch.conf` to Docker container image. + - Add ppc64le, arm64(experimental) builds. + - Compile with `Go 1.8.3`. + +### Changed + +- v3 client + - `LeaseTimeToLive` returns TTL=-1 resp on lease not found. + - `clientv3.NewFromConfigFile` is moved to `clientv3/yaml.NewConfig`. + - concurrency package's elections updated to match RPC interfaces. + - let client dial endpoints not in the balancer. +- Dependencies + - Update [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) to `v1.2.1`. + - Update [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) to `v1.2.0`. + +### Fixed + +- Allow v2 snapshot over 512MB. + + +## [v3.1.9](https://github.com/coreos/etcd/releases/tag/v3.1.9) (2017-06-09) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.8...v3.1.9) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Fixed + +- Allow v2 snapshot over 512MB. + + +## [v3.1.8](https://github.com/coreos/etcd/releases/tag/v3.1.8) (2017-05-19) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.7...v3.1.8) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + + +## [v3.1.7](https://github.com/coreos/etcd/releases/tag/v3.1.7) (2017-04-28) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.6...v3.1.7) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + + +## [v3.1.6](https://github.com/coreos/etcd/releases/tag/v3.1.6) (2017-04-19) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.5...v3.1.6) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Changed + +- Remove auth check in Status API. + +### Fixed + +- Fill in Auth API response header. + + +## [v3.1.5](https://github.com/coreos/etcd/releases/tag/v3.1.5) (2017-03-27) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.4...v3.1.5) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Added + +- Add `/etc/nsswitch.conf` file to alpine-based Docker image. + +### Fixed + +- Fix raft memory leak issue. +- Fix Windows file path issues. + + +## [v3.1.4](https://github.com/coreos/etcd/releases/tag/v3.1.4) (2017-03-22) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.3...v3.1.4) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + + +## [v3.1.3](https://github.com/coreos/etcd/releases/tag/v3.1.3) (2017-03-10) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.2...v3.1.3) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Changed + +- Use machine default host when advertise URLs are default values(`localhost:2379,2380`) AND if listen URL is `0.0.0.0`. + +### Fixed + +- Fix `etcd gateway` schema handling in DNS discovery. +- Fix sd_notify behaviors in `gateway`, `grpc-proxy`. + + +## [v3.1.2](https://github.com/coreos/etcd/releases/tag/v3.1.2) (2017-02-24) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.1...v3.1.2) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Changed + +- Use IPv4 default host, by default (when IPv4 and IPv6 are available). + +### Fixed + +- Fix `etcd gateway` with multiple endpoints. + + +## [v3.1.1](https://github.com/coreos/etcd/releases/tag/v3.1.1) (2017-02-17) + +See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.1.1) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Changed + +- Compile with `Go 1.7.5`. + + +## [v2.3.8](https://github.com/coreos/etcd/releases/tag/v2.3.8) (2017-02-17) + +See [code changes](https://github.com/coreos/etcd/compare/v2.3.7...v2.3.8). + +### Changed + +- Compile with `Go 1.7.5`. + + +## [v3.1.0](https://github.com/coreos/etcd/releases/tag/v3.1.0) (2017-01-20) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.1.0) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. + +### Improved + +- Faster linearizable reads (implements Raft read-index). +- v3 authentication API is now stable. + +### Added + +- Automatic leadership transfer when leader steps down. +- etcd flags + - `--strict-reconfig-check` flag is set by default. + - Add `--log-output` flag. + - Add `--metrics` flag. +- v3 client + - Add `SetEndpoints` method; update endpoints at runtime. + - Add `Sync` method; auto-update endpoints at runtime. + - Add `Lease TimeToLive` API; fetch lease information. + - replace Config.Logger field with global logger. + - Get API responses are sorted in ascending order by default. +- v3 etcdctl + - Add `lease timetolive` command. + - Add `--print-value-only` flag to get command. + - Add `--dest-prefix` flag to make-mirror command. + - `get` command responses are sorted in ascending order by default. +- `recipes` now conform to sessions defined in `clientv3/concurrency`. +- ACI has symlinks to `/usr/local/bin/etcd*`. +- Experimental gRPC proxy feature. + +### Changed + +- Deprecated following gRPC metrics in favor of [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus): + - `etcd_grpc_requests_total` + - `etcd_grpc_requests_failed_total` + - `etcd_grpc_active_streams` + - `etcd_grpc_unary_requests_duration_seconds` +- etcd uses default route IP if advertise URL is not given. +- Cluster rejects removing members if quorum will be lost. +- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given. + - `TLSConfig.ServerName` is ignored with user-provided certificates for backwards compatibility; to be deprecated. + - For example, `etcd --discovery-srv=example.com` will only authenticate peers/clients when the provided certs have root domain `example.com` as an entry in Subject Alternative Name (SAN) field. +- Discovery now has upper limit for waiting on retries. +- Warn on binding listeners through domain names; to be deprecated. + + +## [v3.0.16](https://github.com/coreos/etcd/releases/tag/v3.0.16) (2016-11-13) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.15...v3.0.16) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.15](https://github.com/coreos/etcd/releases/tag/v3.0.15) (2016-11-11) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.14...v3.0.15) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Fixed + +- Fix cancel watch request with wrong range end. + + +## [v3.0.14](https://github.com/coreos/etcd/releases/tag/v3.0.14) (2016-11-04) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.13...v3.0.14) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Added + +- v3 `etcdctl migrate` command now supports `--no-ttl` flag to discard keys on transform. + + +## [v3.0.13](https://github.com/coreos/etcd/releases/tag/v3.0.13) (2016-10-24) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.12...v3.0.13) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.12](https://github.com/coreos/etcd/releases/tag/v3.0.12) (2016-10-07) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.11...v3.0.12) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.11](https://github.com/coreos/etcd/releases/tag/v3.0.11) (2016-10-07) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.10...v3.0.11) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Added + +- Server returns previous key-value (optional) + - `clientv3.WithPrevKV` option + - v3 etcdctl `put,watch,del --prev-kv` flag + + +## [v3.0.10](https://github.com/coreos/etcd/releases/tag/v3.0.10) (2016-09-23) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.9...v3.0.10) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.9](https://github.com/coreos/etcd/releases/tag/v3.0.9) (2016-09-15) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.8...v3.0.9) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Added + +- Warn on domain names on listen URLs (v3.2 will reject domain names). + + +## [v3.0.8](https://github.com/coreos/etcd/releases/tag/v3.0.8) (2016-09-09) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.7...v3.0.8) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- Allow only IP addresses in listen URLs (domain names are rejected). + + +## [v3.0.7](https://github.com/coreos/etcd/releases/tag/v3.0.7) (2016-08-31) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.6...v3.0.7) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- SRV records only allow A records (RFC 2052). + + +## [v3.0.6](https://github.com/coreos/etcd/releases/tag/v3.0.6) (2016-08-19) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.5...v3.0.6) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.5](https://github.com/coreos/etcd/releases/tag/v3.0.5) (2016-08-19) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.4...v3.0.5) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given. + + +## [v3.0.4](https://github.com/coreos/etcd/releases/tag/v3.0.4) (2016-07-27) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.3...v3.0.4) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- v2 auth can now use common name from TLS certificate when `--client-cert-auth` is enabled. + +### Added + +- v2 `etcdctl ls` command now supports `--output=json`. +- Add /var/lib/etcd directory to etcd official Docker image. + + +## [v3.0.3](https://github.com/coreos/etcd/releases/tag/v3.0.3) (2016-07-15) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.2...v3.0.3) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- Revert Dockerfile to use `CMD`, instead of `ENTRYPOINT`, to support `etcdctl` run. + - Docker commands for v3.0.2 won't work without specifying executable binary paths. +- v3 etcdctl default endpoints are now `127.0.0.1:2379`. + + +## [v3.0.2](https://github.com/coreos/etcd/releases/tag/v3.0.2) (2016-07-08) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.1...v3.0.2) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + +### Changed + +- Dockerfile uses `ENTRYPOINT`, instead of `CMD`, to run etcd without binary path specified. + + +## [v3.0.1](https://github.com/coreos/etcd/releases/tag/v3.0.1) (2016-07-01) + +See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.0.1) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. + + +## [v3.0.0](https://github.com/coreos/etcd/releases/tag/v3.0.0) (2016-06-30) + +See [code changes](https://github.com/coreos/etcd/compare/v2.3.0...v3.0.0) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes. diff --git a/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md b/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..c0c20dd815 --- /dev/null +++ b/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md @@ -0,0 +1,63 @@ +## CoreOS Community Code of Conduct + +### Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing others' private information, such as physical or electronic addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct. By adopting this Code of Conduct, +project maintainers commit themselves to fairly and consistently applying these +principles to every aspect of managing this project. Project maintainers who do +not follow or enforce the Code of Conduct may be permanently removed from the +project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer, Brandon Philips +, and/or Meghan Schofield +. + +This Code of Conduct is adapted from the Contributor Covenant +(http://contributor-covenant.org), version 1.2.0, available at +http://contributor-covenant.org/version/1/2/0/ + +### CoreOS Events Code of Conduct + +CoreOS events are working conferences intended for professional networking and +collaboration in the CoreOS community. Attendees are expected to behave +according to professional standards and in accordance with their employer’s +policies on appropriate workplace behavior. + +While at CoreOS events or related social networking opportunities, attendees +should not engage in discriminatory or offensive speech or actions including +but not limited to gender, sexuality, race, age, disability, or religion. +Speakers should be especially aware of these concerns. + +CoreOS does not condone any statements by speakers contrary to these standards. +CoreOS reserves the right to deny entrance and/or eject from an event (without +refund) any individual found to be engaging in discriminatory or offensive +speech or actions. + +Please bring any concerns to the immediate attention of designated on-site +staff, Brandon Philips , and/or Meghan Schofield +. diff --git a/vendor/github.com/coreos/etcd/CONTRIBUTING.md b/vendor/github.com/coreos/etcd/CONTRIBUTING.md index 736f3f2d69..31cef1fa0d 100644 --- a/vendor/github.com/coreos/etcd/CONTRIBUTING.md +++ b/vendor/github.com/coreos/etcd/CONTRIBUTING.md @@ -1,11 +1,11 @@ # How to contribute -etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. This document outlines some of the conventions on commit message formatting, contact points for developers and other resources to make getting your contribution into etcd easier. +etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. This document outlines some of the conventions on commit message formatting, contact points for developers, and other resources to help get contributions into etcd. # Email and chat - Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev) -- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org +- IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) IRC channel on freenode.org ## Getting started @@ -14,24 +14,20 @@ etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. ## Reporting bugs and creating issues -Reporting bugs is one of the best ways to contribute. However, a good bug report -has some very specific qualities, so please read over our short document on -[reporting bugs](https://github.com/coreos/etcd/blob/master/Documentation/reporting_bugs.md) -before you submit your bug report. This document might contain links known -issues, another good reason to take a look there, before reporting your bug. +Reporting bugs is one of the best ways to contribute. However, a good bug report has some very specific qualities, so please read over our short document on [reporting bugs](https://github.com/coreos/etcd/blob/master/Documentation/reporting_bugs.md) before submitting a bug report. This document might contain links to known issues, another good reason to take a look there before reporting a bug. ## Contribution flow This is a rough outline of what a contributor's workflow looks like: -- Create a topic branch from where you want to base your work. This is usually master. +- Create a topic branch from where to base the contribution. This is usually master. - Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. +- Make sure commit messages are in the proper format (see below). +- Push changes in a topic branch to a personal fork of the repository. - Submit a pull request to coreos/etcd. -- Your PR must receive a LGTM from two maintainers found in the MAINTAINERS file. +- The PR must receive a LGTM from two maintainers found in the MAINTAINERS file. -Thanks for your contributions! +Thanks for contributing! ### Code style @@ -48,8 +44,7 @@ the body of the commit should describe the why. ``` scripts: add the test-cluster command -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. +this uses tmux to setup a test cluster that can easily be killed and started for debugging. Fixes #38 ``` @@ -64,7 +59,4 @@ The format can be described more formally as follows: