├── web ├── .gitignore ├── public │ ├── favicon.png │ ├── index.html │ ├── build │ │ ├── bundle.css │ │ └── bundle.css.map │ └── global.css ├── src │ ├── main.js │ ├── jsonrpc.js │ ├── App.svelte │ ├── Wallet.svelte │ └── Explorer.svelte ├── package.json ├── rollup.config.js ├── README.md ├── scripts │ └── setupTypeScript.js └── package-lock.json ├── .gitignore ├── demo.gif ├── config └── default.toml ├── src ├── lib.rs ├── web.rs ├── block.rs ├── settings.rs ├── crypto.rs ├── tx.rs ├── miner.rs ├── bin │ ├── nibbled.rs │ └── nibble-cli.rs ├── rpc.rs ├── storage.rs ├── node.rs └── p2p.rs ├── Cargo.toml ├── README.md └── Cargo.lock /web/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | data 3 | *.config.toml 4 | *_data/ 5 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monokh/nibble/HEAD/demo.gif -------------------------------------------------------------------------------- /web/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monokh/nibble/HEAD/web/public/favicon.png -------------------------------------------------------------------------------- /config/default.toml: -------------------------------------------------------------------------------- 1 | rpc_port = 1337 2 | tcp_port = 1338 3 | web_port = 1339 4 | data_dir = "data" 5 | miner_enabled = false -------------------------------------------------------------------------------- /web/src/main.js: -------------------------------------------------------------------------------- 1 | import App from './App.svelte'; 2 | 3 | var app = new App({ 4 | target: document.body 5 | }); 6 | 7 | export default app; -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod node; 2 | pub mod settings; 3 | pub mod block; 4 | pub mod tx; 5 | pub mod crypto; 6 | pub mod storage; 7 | pub mod miner; 8 | pub mod rpc; 9 | pub mod p2p; 10 | pub mod web; -------------------------------------------------------------------------------- /web/src/jsonrpc.js: -------------------------------------------------------------------------------- 1 | export async function call (rpc, method, params) { 2 | return fetch(rpc, { 3 | method: 'POST', 4 | body: JSON.stringify({ 5 | jsonrpc: "2.0", 6 | id: 1, 7 | method, 8 | params 9 | }), 10 | headers: { 11 | 'Content-Type': 'application/json' 12 | }, 13 | }).then(function(response) { 14 | return response.json(); 15 | }).then(function(json) { 16 | return json.result; 17 | }) 18 | } -------------------------------------------------------------------------------- /web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svelte app 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "build": "rollup -c", 6 | "dev": "rollup -c -w", 7 | "start": "sirv public" 8 | }, 9 | "devDependencies": { 10 | "@rollup/plugin-commonjs": "^14.0.0", 11 | "@rollup/plugin-node-resolve": "^8.0.0", 12 | "rollup": "^2.3.4", 13 | "rollup-plugin-livereload": "^2.0.0", 14 | "rollup-plugin-svelte": "^6.0.0", 15 | "rollup-plugin-terser": "^7.0.0", 16 | "svelte": "^3.0.0" 17 | }, 18 | "dependencies": { 19 | "sirv-cli": "^1.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/web.rs: -------------------------------------------------------------------------------- 1 | use colored::*; 2 | use rouille::Response; 3 | 4 | pub fn run_server (port: u32) { 5 | let path = format!("127.0.0.1:{}", port); 6 | println!("{} Wallet, Explorer running on {}", "WEB:".green(), path); 7 | rouille::start_server(path, move |request| { 8 | let response = rouille::match_assets(&request, "web/public"); 9 | if response.is_success() { 10 | return response; 11 | } else if request.url() == "/" { 12 | return rouille::match_assets(&request, "web/public/index.html"); 13 | } else { 14 | return Response::text("404").with_status_code(404); 15 | } 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /web/src/App.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 | 31 | 32 |
33 |

NIBBLE

34 |
35 | Node: 36 |
37 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /src/block.rs: -------------------------------------------------------------------------------- 1 | use crate::tx; 2 | 3 | use serde::{Serialize, Deserialize}; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub struct Block { 7 | pub hash: String, 8 | pub prev_block: String, 9 | pub nonce: u32, 10 | pub transactions: Vec, 11 | } 12 | 13 | impl Block { 14 | pub fn serialize(&self) -> String { 15 | let txs = self.transactions.iter().fold(String::new(), |a, b| a + &b.to_string()); 16 | return format!("{}{}{}", self.prev_block, txs, self.nonce) 17 | } 18 | } 19 | 20 | pub struct ProposedBlock { 21 | pub prev_block: String, 22 | pub transactions: Vec 23 | } 24 | 25 | impl ProposedBlock { 26 | pub fn serialize(&self) -> String { 27 | let txs = self.transactions.iter().fold(String::new(), |a, b| a + &b.to_string()); 28 | return format!("{}{}", self.prev_block, txs) 29 | } 30 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nibble" 3 | version = "0.2.0" 4 | authors = ["monokh "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | regex = "1" 11 | hex = "0.4.2" 12 | toml = "0.5.6" 13 | config = "0.10.1" 14 | sha2 = "0.9.1" 15 | generic-array = "0.14.2" 16 | typenum = "1.12.0" 17 | clap = "2.33.1" 18 | rouille = "3.0.0" 19 | colored = "2.0.0" 20 | serde = { version = "1.0.114", features = ["derive"] } 21 | serde_json = "1.0.57" 22 | jsonrpc-core = "14.2.0" 23 | jsonrpc-http-server = "14.2.0" 24 | jsonrpc-derive = "14.2.1" 25 | rocksdb = "0.14.0" 26 | reqwest = { version = "0.10.7", features = ["json"] } 27 | tokio = { version = "0.2.22", features = ["full"] } 28 | jsonrpc-client-http = "0.5.0" 29 | jsonrpc-client-core = "0.5.0" 30 | jsonrpc-core-client = { version = "14.2.0", features = ["http"] } 31 | 32 | [dependencies.secp256k1] 33 | version = "0.17.2" 34 | features = ["rand-std", "serde"] 35 | -------------------------------------------------------------------------------- /src/settings.rs: -------------------------------------------------------------------------------- 1 | use config::{ConfigError, Config, File}; 2 | use serde::Deserialize; 3 | use std::env; 4 | 5 | #[derive(Deserialize)] 6 | pub struct Settings { 7 | pub rpc_port: u32, 8 | pub tcp_port: u32, 9 | pub web_port: u32, 10 | pub data_dir: String, 11 | pub miner_enabled: bool, 12 | pub bootstrap_node: Option, 13 | } 14 | 15 | impl Settings { 16 | pub fn new() -> Result { 17 | let mut s = Config::new(); 18 | 19 | // Start off by merging in the "default" configuration file 20 | s.merge(File::with_name("config/default"))?; 21 | 22 | // Config in home dir 23 | s.merge(File::with_name("~/.nibble/config.toml").required(false))?; 24 | 25 | // Config in local dir 26 | let local_config = env::args().nth(1).unwrap_or("config".to_string()); 27 | s.merge(File::with_name(&local_config).required(false))?; 28 | 29 | // You can deserialize (and thus freeze) the entire configuration as 30 | s.try_into() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nibble :cookie: 2 | 3 | Nibble is a re creation of Bitcoin as a concept. It is intended to create a simple view of Bitcoin with code. It will be built from simple data structures and processes, eventually becoming ~~a network that anyone can run~~ **FAILED** 4 | 5 | ![Nibble demo](https://github.com/monokh/nibble/blob/master/demo.gif?raw=true) 6 | 7 | ## Run 8 | 9 | `cargo run --bin nibbled` 10 | 11 | RPC interface: `http://localhost:1337` 12 | 13 | Explorer and Wallet UI: `http://localhost:1339` 14 | 15 | ## Guide 16 | 17 | Data Structures: https://monokh.com/posts/bitcoin-from-scratch-part-1 18 | 19 | The Node: https://monokh.com/posts/bitcoin-from-scratch-part-2 20 | 21 | The Network: https://monokh.com/posts/bitcoin-from-scratch-part-3 22 | 23 | ## CLI 24 | 25 | ``` 26 | USAGE: 27 | nibble-cli [OPTIONS] [SUBCOMMAND] 28 | 29 | FLAGS: 30 | -h, --help Prints help information 31 | -V, --version Prints version information 32 | 33 | OPTIONS: 34 | -r, --rpc-url RPC Url to connect to [default: http://localhost:1337] 35 | 36 | SUBCOMMANDS: 37 | balances Returns balances for each pubkey known by the node 38 | blockheight Get the current block height 39 | getbalance Pubkey 40 | getblock Block Number 41 | getpubkey Get node's public key 42 | help Prints this message or the help of the given subcommand(s) 43 | mempool Returns the transactions in the mempool 44 | newpubkey Generate a random pubkey 45 | send Amount to send 46 | ``` 47 | -------------------------------------------------------------------------------- /web/public/build/bundle.css: -------------------------------------------------------------------------------- 1 | .container.svelte-jdyva7{width:1100px;margin:0 auto;display:grid;grid-template-columns:33% 67%;grid-template-rows:auto auto auto;grid-template-areas:"header rpc" 2 | "wallet explorer"}h1.svelte-jdyva7{color:#000000;grid-area:header}.rpc.svelte-jdyva7{grid-area:rpc;text-align:right;align-self:center} 3 | .explorer.svelte-19rqxfk.svelte-19rqxfk{padding:0 20px 20px 20px;margin-left:20px;border:1px solid #b9b9b9}.table.svelte-19rqxfk.svelte-19rqxfk{width:100%;table-layout:fixed;border-collapse:collapse}.table.svelte-19rqxfk thead.svelte-19rqxfk,.table.svelte-19rqxfk tr.svelte-19rqxfk{border-bottom:1px solid #9e9e9e}.table.svelte-19rqxfk td.svelte-19rqxfk{padding-top:10px;padding-right:10px}.table.svelte-19rqxfk thead.svelte-19rqxfk{font-weight:bold}.table.svelte-19rqxfk thead td.svelte-19rqxfk:nth-child(3){width:100px}.table.svelte-19rqxfk td.svelte-19rqxfk{padding-bottom:10px}.table.svelte-19rqxfk tr td.svelte-19rqxfk{overflow:hidden;text-overflow:ellipsis}.table.svelte-19rqxfk tr td.svelte-19rqxfk:hover{overflow:show;text-overflow:initial;overflow-wrap:break-word}.blocks.svelte-19rqxfk.svelte-19rqxfk{display:flex;flex-direction:row}.block-list.svelte-19rqxfk.svelte-19rqxfk{align-items:center;height:400px;overflow-y:scroll;padding-right:10px}.block-list.svelte-19rqxfk button.svelte-19rqxfk{display:block;width:100px;padding:10px 10px 8px;margin-bottom:10px}.block-detail.svelte-19rqxfk.svelte-19rqxfk{flex:1;padding-left:20px} 4 | .wallet.svelte-yz4xpt{padding:0 20px 20px 20px;border:1px solid #b9b9b9}.grid.svelte-yz4xpt{display:grid;grid-template-rows:auto auto;grid-template-columns:auto 1fr;grid-gap:10px;align-items:center} 5 | 6 | /*# sourceMappingURL=bundle.css.map */ -------------------------------------------------------------------------------- /src/crypto.rs: -------------------------------------------------------------------------------- 1 | use sha2::{Sha256, Digest}; 2 | use secp256k1::{Secp256k1, Message}; 3 | use secp256k1::rand; 4 | use secp256k1::All; 5 | use secp256k1::Signature; 6 | use std::str::FromStr; 7 | 8 | pub mod key { 9 | pub use secp256k1::key::PublicKey; 10 | pub use secp256k1::key::SecretKey; 11 | } 12 | 13 | pub fn sha256 (payload: String) -> Vec { 14 | let mut hasher = Sha256::new(); 15 | hasher.update(payload); 16 | return hasher.finalize().as_slice().to_vec() 17 | } 18 | 19 | pub struct KeyPair { 20 | secp: Secp256k1, // TODO: how to make this global? 21 | pub public_key: key::PublicKey, 22 | pub private_key: key::SecretKey, 23 | } 24 | 25 | impl KeyPair { 26 | pub fn new() -> KeyPair { 27 | #[allow(deprecated)] 28 | let mut rand = rand::OsRng::new().unwrap(); 29 | let secp = Secp256k1::new(); 30 | let (private_key, public_key) = secp.generate_keypair(&mut rand); 31 | KeyPair { 32 | secp, 33 | public_key, 34 | private_key, 35 | } 36 | } 37 | 38 | pub fn from(key: String) -> Result { 39 | let secp = Secp256k1::new(); 40 | let private_key = key::SecretKey::from_str(&key)?; 41 | let public_key = key::PublicKey::from_secret_key(&secp, &private_key); 42 | return Ok(KeyPair { 43 | secp, 44 | public_key, 45 | private_key, 46 | }); 47 | } 48 | 49 | pub fn sign(&self, message: &[u8]) -> Signature { 50 | let message = Message::from_slice(message).expect("message from slice"); 51 | return self.secp.sign(&message, &self.private_key); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /web/public/global.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | position: relative; 3 | width: 100%; 4 | height: 100%; 5 | } 6 | 7 | body { 8 | font-size: 14px; 9 | color: #333; 10 | margin: 0; 11 | padding: 20px; 12 | box-sizing: border-box; 13 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; 14 | } 15 | 16 | a { 17 | color: rgb(0,100,200); 18 | text-decoration: none; 19 | } 20 | 21 | a:hover { 22 | text-decoration: underline; 23 | } 24 | 25 | a:visited { 26 | color: rgb(0,80,160); 27 | } 28 | 29 | label { 30 | display: block; 31 | } 32 | 33 | input, button, select, textarea { 34 | font-family: inherit; 35 | font-size: inherit; 36 | -webkit-padding: 0.4em 0; 37 | padding: 0.4em; 38 | box-sizing: border-box; 39 | border: 1px solid #ccc; 40 | border-radius: 2px; 41 | } 42 | 43 | input:disabled { 44 | color: #ccc; 45 | } 46 | 47 | button { 48 | cursor: pointer; 49 | position:relative; 50 | width: auto; 51 | display:inline-block; 52 | color:#ecf0f1; 53 | text-decoration:none; 54 | border-radius:5px; 55 | border:solid 1px #9c9c9c; 56 | background:#8d8680; 57 | text-align:center; 58 | padding:6px 10px 4px; 59 | 60 | -webkit-transition: all 0.1s; 61 | -moz-transition: all 0.1s; 62 | transition: all 0.1s; 63 | 64 | -webkit-box-shadow: 0px 6px 0px #6b6b6b; 65 | -moz-box-shadow: 0px 6px 0px #6b6b6b; 66 | box-shadow: 0px 6px 0px #6b6b6b; 67 | } 68 | 69 | button:active, button.selected { 70 | -webkit-box-shadow: 0px 2px 0px #6b6b6b; 71 | -moz-box-shadow: 0px 2px 0px #6b6b6b; 72 | box-shadow: 0px 2px 0px #6b6b6b; 73 | position:relative; 74 | top:4px; 75 | } 76 | 77 | button:focus { 78 | outline: none; 79 | 80 | } 81 | 82 | h1, h2, h3, h4, h5 { 83 | color: #5a5a5a; 84 | } 85 | 86 | hr { 87 | height: 1px; 88 | background: rgb(216, 216, 216); 89 | border: 0; 90 | margin: 20px 0; 91 | } -------------------------------------------------------------------------------- /web/rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from 'rollup-plugin-svelte'; 2 | import resolve from '@rollup/plugin-node-resolve'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import livereload from 'rollup-plugin-livereload'; 5 | import { terser } from 'rollup-plugin-terser'; 6 | 7 | const production = !process.env.ROLLUP_WATCH; 8 | 9 | function serve() { 10 | let server; 11 | 12 | function toExit() { 13 | if (server) server.kill(0); 14 | } 15 | 16 | return { 17 | writeBundle() { 18 | if (server) return; 19 | server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { 20 | stdio: ['ignore', 'inherit', 'inherit'], 21 | shell: true 22 | }); 23 | 24 | process.on('SIGTERM', toExit); 25 | process.on('exit', toExit); 26 | } 27 | }; 28 | } 29 | 30 | export default { 31 | input: 'src/main.js', 32 | output: { 33 | sourcemap: true, 34 | format: 'iife', 35 | name: 'app', 36 | file: 'public/build/bundle.js' 37 | }, 38 | plugins: [ 39 | svelte({ 40 | // enable run-time checks when not in production 41 | dev: !production, 42 | // we'll extract any component CSS out into 43 | // a separate file - better for performance 44 | css: css => { 45 | css.write('bundle.css'); 46 | } 47 | }), 48 | 49 | // If you have external dependencies installed from 50 | // npm, you'll most likely need these plugins. In 51 | // some cases you'll need additional configuration - 52 | // consult the documentation for details: 53 | // https://github.com/rollup/plugins/tree/master/packages/commonjs 54 | resolve({ 55 | browser: true, 56 | dedupe: ['svelte'] 57 | }), 58 | commonjs(), 59 | 60 | // In dev mode, call `npm run start` once 61 | // the bundle has been generated 62 | !production && serve(), 63 | 64 | // Watch the `public` directory and refresh the 65 | // browser on changes when not in production 66 | !production && livereload('public'), 67 | 68 | // If we're building for production (npm run build 69 | // instead of npm run dev), minify 70 | production && terser() 71 | ], 72 | watch: { 73 | clearScreen: false 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /src/tx.rs: -------------------------------------------------------------------------------- 1 | use crate::crypto; 2 | 3 | use crypto::key; 4 | use secp256k1::key::PublicKey; 5 | use secp256k1::{Secp256k1, Signature, Message}; 6 | use std::str::FromStr; 7 | use std::fmt; 8 | use serde::{Serialize, Deserialize}; 9 | 10 | #[derive(Copy, Clone, Serialize, Deserialize)] 11 | pub struct Transaction { 12 | pub from: PublicKey, 13 | pub to: PublicKey, 14 | pub amount: u32 15 | } 16 | 17 | impl fmt::Debug for Transaction { 18 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 19 | f.debug_struct("Transaction") 20 | .field("from", &format!("{}", self.from)) 21 | .field("to", &format!("{}", self.to)) 22 | .field("amount", &self.amount) 23 | .finish() 24 | } 25 | } 26 | 27 | impl Transaction{ 28 | pub fn serialize(&self) -> String { 29 | return format!("{}{}{}", self.from, &self.to, hex::encode(&format!("{}", self.amount))); 30 | } 31 | 32 | pub fn hash(&self) -> Vec { 33 | return crypto::sha256(self.serialize()) 34 | } 35 | } 36 | 37 | #[derive(Debug, Clone, Serialize, Deserialize)] 38 | pub struct SignedTransaction { 39 | pub transaction: Transaction, 40 | pub sig: String, 41 | } 42 | 43 | impl SignedTransaction{ 44 | pub fn to_string(& self) -> String { 45 | return format!("{}{}", self.transaction.serialize(), self.sig); 46 | } 47 | 48 | pub fn is_sig_valid(& self) -> bool { 49 | let secp = Secp256k1::verification_only(); 50 | let unsigned_tx_hash = Message::from_slice(self.transaction.hash().as_slice()).expect("message from slice"); 51 | let sig = Signature::from_str(self.sig.as_str()).expect("signature from string"); 52 | return secp.verify(&unsigned_tx_hash, &sig, &self.transaction.from).is_ok(); 53 | } 54 | } 55 | 56 | pub fn create_signed(keypair: &crypto::KeyPair, to: key::PublicKey, amount: u32) -> SignedTransaction { 57 | let tx = Transaction { 58 | from: keypair.public_key, 59 | to, 60 | amount, 61 | }; 62 | 63 | let sig = keypair.sign(&tx.hash()); 64 | 65 | return SignedTransaction{ 66 | transaction: tx, 67 | sig: sig.to_string(), 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /src/miner.rs: -------------------------------------------------------------------------------- 1 | use crate::node; 2 | use crate::block; 3 | use crate::crypto; 4 | 5 | use colored::*; 6 | use std::time; 7 | use std::sync::mpsc; 8 | use std::thread; 9 | use std::sync::{Arc, Mutex}; 10 | 11 | pub fn start_miner(node_ref: Arc>, interrupt_rx: mpsc::Receiver<()>) { 12 | let (out_tx, out_rx) = mpsc::channel(); 13 | let (in_tx, in_rx) = mpsc::channel(); 14 | thread::spawn(move || { 15 | loop { 16 | if let Ok(proposed_block) = out_rx.try_recv() { 17 | let proposed_block: block::ProposedBlock = proposed_block; 18 | 19 | let mut nonce: u32 = 0; 20 | let block_string = proposed_block.serialize(); 21 | loop { 22 | if let Ok(()) = interrupt_rx.try_recv() { 23 | in_tx.send(None).unwrap(); 24 | break; 25 | } 26 | let block = format!("{}{}", block_string, nonce); 27 | let block_hash = hex::encode(crypto::sha256(block.clone())); 28 | if block_hash.starts_with(&"0".repeat(node::DIFFICULTY)) { 29 | let mined_block = block::Block { 30 | hash: block_hash, 31 | nonce, 32 | prev_block: proposed_block.prev_block, 33 | transactions: proposed_block.transactions 34 | }; 35 | in_tx.send(Some(mined_block)).unwrap(); 36 | break; 37 | } 38 | // Artificially limit hash rate to avoid unnecessary cpu usage 39 | thread::sleep(time::Duration::from_millis(80)); 40 | nonce += 1; 41 | } 42 | } 43 | thread::sleep(time::Duration::from_millis(500)); 44 | } 45 | }); 46 | { 47 | let mut node = node_ref.lock().unwrap(); 48 | let proposed_block = node.get_proposed_block().unwrap(); 49 | out_tx.send(proposed_block).unwrap(); 50 | } 51 | loop { 52 | if let Ok(block) = in_rx.try_recv() { 53 | let mut node = node_ref.lock().unwrap(); 54 | if let Some(block) = block { 55 | println!("{} {}", "Mined Block:".green(), block.hash); 56 | node.receive_block(block).unwrap(); 57 | } 58 | let proposed_block = node.get_proposed_block().unwrap(); 59 | out_tx.send(proposed_block).unwrap(); 60 | }; 61 | thread::sleep(time::Duration::from_millis(1000)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/bin/nibbled.rs: -------------------------------------------------------------------------------- 1 | use nibble::node::Node; 2 | use nibble::miner; 3 | use nibble::rpc; 4 | use nibble::p2p; 5 | use nibble::web; 6 | use nibble::settings; 7 | 8 | use colored::*; 9 | use std::sync::{Arc, Mutex}; 10 | use std::sync::mpsc; 11 | use std::thread; 12 | 13 | fn main() -> std::io::Result<()> { 14 | let config = settings::Settings::new().unwrap(); 15 | 16 | let p2p_data = p2p::P2PData::new(); 17 | let p2p_data_ref = Arc::new(Mutex::new(p2p_data)); 18 | 19 | // Broadcasting blocks and transactions 20 | let (block_tx, block_rx) = mpsc::channel(); 21 | let (transaction_tx, transaction_rx) = mpsc::channel(); 22 | 23 | // Interrupt the miner when new blocks are received through the network 24 | let (miner_interrupt_tx, miner_interrupt_rx) = mpsc::channel(); 25 | 26 | let receiver_p2p_data_ref = p2p_data_ref.clone(); 27 | let receiver_thread = thread::spawn(move || { 28 | p2p::run_receiver(receiver_p2p_data_ref, block_rx, transaction_rx); 29 | }); 30 | 31 | let node = Node::new(block_tx, transaction_tx); 32 | let node_ref = Arc::new(Mutex::new(node)); 33 | { 34 | let mut node_inst = node_ref.lock().unwrap(); 35 | node_inst.start().expect("Start failed"); 36 | println!("{}", format!("Your Public Key: {}", node_inst.keypair.public_key).yellow()); 37 | } 38 | 39 | let rpc_node_ref = node_ref.clone(); 40 | let rpc_port = config.rpc_port.clone(); 41 | let rpc_thread = thread::spawn(move || { 42 | rpc::run_server(rpc_node_ref, rpc_port) 43 | }); 44 | 45 | let p2p_node_ref = node_ref.clone(); 46 | let tcp_port = config.tcp_port.clone(); 47 | let server_p2p_data_ref = p2p_data_ref.clone(); 48 | let host_addr = format!("127.0.0.1:{}", tcp_port); // TODO: real address 49 | let run_server_host_addr = host_addr.clone(); 50 | let p2p_miner_interrupt_tx = miner_interrupt_tx.clone(); 51 | let p2p_thread = thread::spawn(move || { 52 | p2p::run_server(p2p_node_ref, server_p2p_data_ref, run_server_host_addr, p2p_miner_interrupt_tx).unwrap(); 53 | }); 54 | 55 | let p2p_node_ref = node_ref.clone(); 56 | let miner_thread = if config.miner_enabled { 57 | let miner_node_ref = node_ref.clone(); 58 | Some(thread::spawn(move || { 59 | miner::start_miner(miner_node_ref, miner_interrupt_rx); 60 | })) 61 | } else { None }; 62 | 63 | let p2p_data_ref = p2p_data_ref.clone(); 64 | let init_host_addr = host_addr.clone(); 65 | p2p::init(p2p_node_ref, p2p_data_ref, miner_interrupt_tx, init_host_addr, config.bootstrap_node).unwrap(); 66 | 67 | let web_port = config.web_port.clone(); 68 | let web_thread = thread::spawn(move || { 69 | web::run_server(web_port) 70 | }); 71 | 72 | rpc_thread.join().unwrap(); 73 | p2p_thread.join().unwrap(); 74 | receiver_thread.join().unwrap(); 75 | match miner_thread { 76 | Some(thread) => thread.join().unwrap(), 77 | None => (), 78 | } 79 | web_thread.join().unwrap(); 80 | 81 | return Ok(()); 82 | } 83 | -------------------------------------------------------------------------------- /web/src/Wallet.svelte: -------------------------------------------------------------------------------- 1 | 49 | 50 | 64 | 65 |
66 |

Wallet

67 |
68 |
Balance:
{#await balance then balance}{balance} Nibble {/await}
69 |
Public Key:
{#await pubKey then pubKey}{/await}
70 |
71 |
72 |

Send

73 |
74 |
To:
75 |
Amount:
76 |
77 |
78 |

Random Public Key

79 |
{#await randomPubKey then randomPubKey}{/await}
80 |
81 |

Get Balance

82 |
83 |
Public Key:
84 | {#if !isNaN(pubKeyBalance)}{pubKeyBalance} Nibble{/if} 85 |
86 |
-------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | *Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)* 2 | 3 | --- 4 | 5 | # svelte app 6 | 7 | This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. 8 | 9 | To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): 10 | 11 | ```bash 12 | npx degit sveltejs/template svelte-app 13 | cd svelte-app 14 | ``` 15 | 16 | *Note that you will need to have [Node.js](https://nodejs.org) installed.* 17 | 18 | 19 | ## Get started 20 | 21 | Install the dependencies... 22 | 23 | ```bash 24 | cd svelte-app 25 | npm install 26 | ``` 27 | 28 | ...then start [Rollup](https://rollupjs.org): 29 | 30 | ```bash 31 | npm run dev 32 | ``` 33 | 34 | Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. 35 | 36 | By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. 37 | 38 | 39 | ## Building and running in production mode 40 | 41 | To create an optimised version of the app: 42 | 43 | ```bash 44 | npm run build 45 | ``` 46 | 47 | You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). 48 | 49 | 50 | ## Single-page app mode 51 | 52 | By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. 53 | 54 | If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: 55 | 56 | ```js 57 | "start": "sirv public --single" 58 | ``` 59 | 60 | ## Using TypeScript 61 | 62 | This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with: 63 | 64 | ```bash 65 | node scripts/setupTypeScript.js 66 | ``` 67 | 68 | Or remove the script via: 69 | 70 | ```bash 71 | rm scripts/setupTypeScript.js 72 | ``` 73 | 74 | ## Deploying to the web 75 | 76 | ### With [Vercel](https://vercel.com) 77 | 78 | Install `vercel` if you haven't already: 79 | 80 | ```bash 81 | npm install -g vercel 82 | ``` 83 | 84 | Then, from within your project folder: 85 | 86 | ```bash 87 | cd public 88 | vercel deploy --name my-project 89 | ``` 90 | 91 | ### With [surge](https://surge.sh/) 92 | 93 | Install `surge` if you haven't already: 94 | 95 | ```bash 96 | npm install -g surge 97 | ``` 98 | 99 | Then, from within your project folder: 100 | 101 | ```bash 102 | npm run build 103 | surge public my-project.surge.sh 104 | ``` 105 | -------------------------------------------------------------------------------- /src/rpc.rs: -------------------------------------------------------------------------------- 1 | use jsonrpc_http_server::jsonrpc_core::{IoHandler}; 2 | use jsonrpc_http_server::{ServerBuilder}; 3 | 4 | use jsonrpc_core::{Result}; 5 | use jsonrpc_derive::rpc; 6 | 7 | use crate::crypto; 8 | use crate::node; 9 | use crate::block; 10 | use crate::tx; 11 | use crate::storage; 12 | 13 | use crypto::key; 14 | use colored::*; 15 | use std::collections::HashMap; 16 | use std::sync::{Arc, Mutex}; 17 | 18 | #[rpc(server, client)] 19 | pub trait Rpc { 20 | #[rpc(name = "protocolVersion")] 21 | fn protocol_version(&self) -> Result; 22 | 23 | #[rpc(name = "send")] 24 | fn send(&self, pubkey: key::PublicKey, amount: u32) -> Result; 25 | 26 | #[rpc(name = "newpubkey")] 27 | fn newpubkey(&self) -> Result; 28 | 29 | #[rpc(name = "getpubkey")] 30 | fn getpubkey(&self) -> Result; 31 | 32 | #[rpc(name = "blockheight")] 33 | fn blockheight(&self) -> Result; 34 | 35 | #[rpc(name = "getblock")] 36 | fn getblock(&self, block_number: u32) -> Result; 37 | 38 | #[rpc(name = "balances")] 39 | fn balances(&self) -> Result>; 40 | 41 | #[rpc(name = "getbalance")] 42 | fn getbalance(&self, pubkey: key::PublicKey) -> Result; 43 | 44 | #[rpc(name = "mempool")] 45 | fn mempool(&self) -> Result>; 46 | } 47 | 48 | struct RpcImpl { 49 | node_ref: Arc>, 50 | } 51 | 52 | impl RpcImpl { 53 | fn new(node_ref: Arc>) -> RpcImpl { 54 | return RpcImpl { 55 | node_ref 56 | } 57 | } 58 | } 59 | 60 | impl Rpc for RpcImpl { 61 | fn protocol_version(&self) -> Result { 62 | Ok("1.0".into()) 63 | } 64 | 65 | fn send(&self, pubkey: key::PublicKey, amount: u32) -> Result { 66 | let mut node = self.node_ref.lock().unwrap(); 67 | let tx = node.send_transaction(pubkey, amount).unwrap(); 68 | return Ok(tx); 69 | } 70 | 71 | fn newpubkey(&self) -> Result { 72 | let random_key = crypto::KeyPair::new(); 73 | return Ok(random_key.public_key.to_string()); 74 | } 75 | 76 | fn getpubkey(&self) -> Result { 77 | let node = self.node_ref.lock().unwrap(); 78 | return Ok(node.keypair.public_key.to_string()); 79 | } 80 | 81 | fn blockheight(&self) -> Result { 82 | let blockheight = storage::get_latest_block_number(&storage::db::blocks_md(true)).unwrap(); 83 | return Ok(blockheight); 84 | } 85 | 86 | fn getblock(&self, block_number: u32) -> Result { 87 | let block_hash = storage::get_block_hash(&storage::db::blocks_md(true), block_number).unwrap().unwrap(); 88 | let block = storage::get_block(&storage::db::blocks(true), &block_hash).unwrap().unwrap(); 89 | return Ok(block) 90 | } 91 | 92 | fn getbalance(&self, pubkey: key::PublicKey) -> Result { 93 | let balance = storage::get_balance(&storage::db::balances(true), pubkey).unwrap(); 94 | return Ok(balance.unwrap_or(0)); 95 | } 96 | 97 | fn balances(&self) -> Result> { 98 | let balances = storage::get_balances(&storage::db::balances(true)).unwrap(); 99 | return Ok(balances); 100 | } 101 | 102 | fn mempool(&self) -> Result> { 103 | let node = self.node_ref.lock().unwrap(); 104 | return Ok(node.mempool.clone()); 105 | } 106 | } 107 | 108 | pub fn run_server (node_ref: Arc>, port: u32) { 109 | let mut io = IoHandler::new(); 110 | let rpc = RpcImpl::new(node_ref); 111 | io.extend_with(rpc.to_delegate()); 112 | 113 | let rpc_path = format!("127.0.0.1:{}", port); 114 | 115 | let server = ServerBuilder::new(io) 116 | .threads(3) 117 | .start_http(&rpc_path.parse().unwrap()) 118 | .unwrap(); 119 | 120 | println!("{} Listening on {}", "RPC:".green(), rpc_path); 121 | 122 | server.wait(); 123 | } -------------------------------------------------------------------------------- /web/scripts/setupTypeScript.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** This script modifies the project to support TS code in .svelte files like: 4 | 5 | 8 | 9 | As well as validating the code for CI. 10 | */ 11 | 12 | /** To work on this script: 13 | rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template 14 | */ 15 | 16 | const fs = require("fs") 17 | const path = require("path") 18 | const { argv } = require("process") 19 | 20 | const projectRoot = argv[2] || path.join(__dirname, "..") 21 | 22 | // Add deps to pkg.json 23 | const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8")) 24 | packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, { 25 | "svelte-check": "^1.0.0", 26 | "svelte-preprocess": "^4.0.0", 27 | "@rollup/plugin-typescript": "^6.0.0", 28 | "typescript": "^3.9.3", 29 | "tslib": "^2.0.0", 30 | "@tsconfig/svelte": "^1.0.0" 31 | }) 32 | 33 | // Add script for checking 34 | packageJSON.scripts = Object.assign(packageJSON.scripts, { 35 | "validate": "svelte-check" 36 | }) 37 | 38 | // Write the package JSON 39 | fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " ")) 40 | 41 | // mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too 42 | const beforeMainJSPath = path.join(projectRoot, "src", "main.js") 43 | const afterMainTSPath = path.join(projectRoot, "src", "main.ts") 44 | fs.renameSync(beforeMainJSPath, afterMainTSPath) 45 | 46 | // Switch the app.svelte file to use TS 47 | const appSveltePath = path.join(projectRoot, "src", "App.svelte") 48 | let appFile = fs.readFileSync(appSveltePath, "utf8") 49 | appFile = appFile.replace(" 42 | 43 | 113 | 114 |
115 |

Mempool

116 |
117 | {#if mempool.length} 118 | 119 | 120 | 121 | 122 | 123 | 124 | {#each mempool as item} 125 | 126 | 127 | 128 | 129 | 130 | {/each} 131 |
FromToValue
{item.transaction.from}{item.transaction.to}{item.transaction.amount}
132 | {:else} 133 | Empty 134 | {/if} 135 |
136 |
137 |

Blocks

138 |
139 |
140 | {#each blocks.slice().reverse() as block (block)} 141 | 146 | {/each} 147 |
148 | {#if selectedBlock} 149 |
150 |

{selectedBlock.hash}

151 | 152 | 153 | 154 | 155 | 156 | 157 | {#each selectedBlock.transactions as item} 158 | 159 | 160 | 161 | 162 | 163 | {/each} 164 |
FromToValue
{item.transaction.from}{item.transaction.to}{item.transaction.amount}
165 |
166 | {/if} 167 |
168 |
-------------------------------------------------------------------------------- /src/storage.rs: -------------------------------------------------------------------------------- 1 | use crate::block; 2 | use crate::crypto; 3 | 4 | use crypto::key; 5 | use rocksdb::{DB}; 6 | use serde_json; 7 | use std::collections::HashMap; 8 | use std::str::FromStr; 9 | 10 | pub mod db { 11 | use rocksdb::{DB, Options}; 12 | use crate::settings; 13 | 14 | static BLOCKS_DB_PATH: &str = "/blocks"; 15 | static BLOCKS_METADATA_DB_PATH: &str = "/blocksmetadata"; 16 | static BALANCES_DB_PATH: &str = "/balances"; 17 | 18 | pub fn open(path: &str, read_only: bool) -> DB { 19 | let config = settings::Settings::new().unwrap(); 20 | let full_path = format!("{}{}", config.data_dir, path); 21 | if read_only { 22 | return DB::open_for_read_only(&Options::default(), full_path, true).unwrap(); 23 | } else { 24 | return DB::open_default(full_path).unwrap(); 25 | } 26 | } 27 | 28 | pub fn blocks(read_only: bool) -> DB { 29 | return open(BLOCKS_DB_PATH, read_only); 30 | } 31 | 32 | pub fn blocks_md(read_only: bool) -> DB { 33 | return open(BLOCKS_METADATA_DB_PATH, read_only); 34 | } 35 | 36 | pub fn balances(read_only: bool) -> DB { 37 | return open(BALANCES_DB_PATH, read_only); 38 | } 39 | } 40 | 41 | pub fn add_block(db: &DB, block: &block::Block) -> Result<(), String> { 42 | let json = serde_json::to_string(block).map_err(|e| e.to_string())?; 43 | db.put(block.hash.clone(), json).map_err(|e| e.to_string())?; 44 | return Ok(()); 45 | } 46 | 47 | pub fn get_block(db: &DB, block_hash: &String) -> Result, String> { 48 | match db.get(block_hash.clone())? { 49 | Some(block) => { 50 | let block_s = String::from_utf8(block).map_err(|e| e.to_string())?; 51 | return Ok(Some(serde_json::from_str(&block_s).map_err(|e| e.to_string())?)); 52 | }, 53 | None => return Ok(None), 54 | } 55 | } 56 | 57 | pub fn set_latest_block(db: &DB, block_hash: &String, height: u32) -> Result<(), String> { 58 | db.put(b"latest_block_hash", block_hash.clone()).map_err(|e| e.to_string())?; 59 | db.put(block_hash.clone(), height.to_string()).map_err(|e| e.to_string())?; 60 | db.put(height.to_string(), block_hash.clone()).map_err(|e| e.to_string())?; 61 | return Ok(()); 62 | } 63 | 64 | pub fn get_latest_block_hash(db: &DB) -> Result, String> { 65 | match db.get(b"latest_block_hash")? { 66 | Some(hash) => return Ok(Some(String::from_utf8(hash).map_err(|e| e.to_string())?)), 67 | None => return Ok(None) 68 | }; 69 | } 70 | 71 | pub fn get_block_height(db: &DB, block_hash: &String) -> Result , String> { 72 | match db.get(block_hash.clone())? { 73 | Some(height) => { 74 | let height_s = String::from_utf8(height).map_err(|e| e.to_string())?; 75 | let height : u32 = height_s.parse().unwrap(); 76 | return Ok(Some(height)); 77 | }, 78 | None => return Ok(None), 79 | } 80 | } 81 | 82 | pub fn get_block_hash(db: &DB, block_number: u32) -> Result , String> { 83 | match db.get(block_number.to_string())? { 84 | Some(block_hash) => { 85 | let block_hash_s = String::from_utf8(block_hash).map_err(|e| e.to_string())?; 86 | return Ok(Some(block_hash_s)); 87 | }, 88 | None => return Ok(None), 89 | } 90 | } 91 | 92 | pub fn set_balance(db: &DB, public_key: key::PublicKey, balance: u32) -> Result <(), String> { 93 | db.put(public_key.to_string(), balance.to_string()).map_err(|e| e.to_string())?; 94 | return Ok(()); 95 | } 96 | 97 | pub fn get_balance(db: &DB, public_key: key::PublicKey) -> Result , String> { 98 | match db.get(public_key.to_string())? { 99 | Some(balance) => { 100 | let balance_s = String::from_utf8(balance).map_err(|e| e.to_string())?; 101 | let balance : u32 = balance_s.parse().unwrap(); 102 | return Ok(Some(balance)); 103 | }, 104 | None => return Ok(None), 105 | }; 106 | } 107 | 108 | pub fn get_balances(db: &DB) -> Result , String> { 109 | let mut balances = HashMap::new(); 110 | let mut iter = db.raw_iterator(); 111 | iter.seek_to_first(); 112 | while iter.valid() { 113 | let public_key = String::from_utf8(iter.key().unwrap().to_vec()).map_err(|e| e.to_string())?; 114 | let balance_s = String::from_utf8(iter.value().unwrap().to_vec()).map_err(|e| e.to_string())?; 115 | let balance : u32 = balance_s.parse().unwrap(); 116 | balances.insert(crypto::key::PublicKey::from_str(&public_key).unwrap(), balance); 117 | iter.next(); 118 | } 119 | return Ok(balances); 120 | } 121 | 122 | pub fn get_block_hashes(db: &DB) -> Result , String> { 123 | let mut blocks = Vec::new(); 124 | let mut iter = db.raw_iterator(); 125 | iter.seek_to_first(); 126 | while iter.valid() { 127 | let block_hash = String::from_utf8(iter.key().unwrap().to_vec()).map_err(|e| e.to_string())?; 128 | if block_hash != "latest_block_hash" { 129 | let block_number_s = String::from_utf8(iter.value().unwrap().to_vec()).map_err(|e| e.to_string())?; 130 | match block_number_s.parse::() { 131 | Ok(block_number) => blocks.push((block_number, block_hash)), 132 | Err(_e) => () 133 | } 134 | } 135 | iter.next(); 136 | } 137 | 138 | blocks.sort_unstable_by(|a, b| a.0.cmp(&b.0)); 139 | 140 | let block_hashes = blocks.iter().map(|x| x.1.clone()).collect(); 141 | 142 | return Ok(block_hashes); 143 | } 144 | 145 | pub fn get_latest_block_number(db: &DB) -> Result{ 146 | let latest_block_hash = match get_latest_block_hash(&db)? { 147 | Some(hash) => hash, 148 | None => return Ok(0) 149 | }; 150 | let latest_block_number = get_block_height(&db, &latest_block_hash)?.unwrap(); 151 | return Ok(latest_block_number); 152 | } 153 | -------------------------------------------------------------------------------- /src/bin/nibble-cli.rs: -------------------------------------------------------------------------------- 1 | use nibble::tx; 2 | use nibble::block; 3 | use nibble::crypto::key; 4 | 5 | use clap::{Arg, App, SubCommand}; 6 | use tokio; 7 | use std::io; 8 | use std::io::Write; 9 | use std::collections::HashMap; 10 | use std::str::FromStr; 11 | use jsonrpc_client_http::HttpTransport; 12 | 13 | #[macro_use] extern crate jsonrpc_client_core; 14 | 15 | jsonrpc_client!(pub struct NibbleClient { 16 | pub fn newpubkey(&mut self) -> RpcRequest; 17 | pub fn getpubkey(&mut self) -> RpcRequest; 18 | pub fn send(&mut self, pubkey: key::PublicKey, amount: u32) -> RpcRequest; 19 | pub fn blockheight(&mut self) -> RpcRequest; 20 | pub fn balances(&mut self) -> RpcRequest>; 21 | pub fn getbalance(&mut self, pubkey: key::PublicKey) -> RpcRequest; 22 | pub fn getblock(&mut self, block_number: u32) -> RpcRequest; 23 | pub fn mempool(&mut self) -> RpcRequest>; 24 | }); 25 | 26 | #[tokio::main] 27 | async fn main() -> Result<(), Box> { 28 | let cli = App::new("Nibble") 29 | .version("1.0") 30 | .author("monokh") 31 | .about("Bitcoin") 32 | .arg(Arg::with_name("rpc-url") 33 | .help("RPC Url to connect to") 34 | .short("rpc") 35 | .long("rpc-url") 36 | .value_name("RPC URL") 37 | .default_value("http://localhost:1337") 38 | .global(true) 39 | ) 40 | .subcommand(SubCommand::with_name("getpubkey") 41 | .about("Get node's public key")) 42 | .subcommand(SubCommand::with_name("newpubkey") 43 | .about("Generate a random pubkey")) 44 | .subcommand(SubCommand::with_name("mempool") 45 | .about("Returns the transactions in the mempool")) 46 | .subcommand(SubCommand::with_name("balances") 47 | .about("Returns balances for each pubkey known by the node")) 48 | .subcommand(SubCommand::with_name("getbalance") 49 | .about("Return the balance of a pubkey") 50 | .arg(Arg::with_name("pubkey") 51 | .required(true) 52 | .index(1)) 53 | .about("Pubkey")) 54 | .subcommand(SubCommand::with_name("getblock") 55 | .about("Return the block at number") 56 | .arg(Arg::with_name("blocknumber") 57 | .required(true) 58 | .index(1)) 59 | .about("Block Number")) 60 | .subcommand(SubCommand::with_name("blockheight") 61 | .about("Get the current block height")) 62 | .subcommand(SubCommand::with_name("send") 63 | .about("Send a transaction") 64 | .arg(Arg::with_name("pubkey") 65 | .required(true) 66 | .index(1)) 67 | .about("Pubkey of receiver") 68 | .arg(Arg::with_name("amount") 69 | .required(true) 70 | .index(2)) 71 | .about("Amount to send")); 72 | 73 | let matches = cli.clone().get_matches(); 74 | let rpc_url = matches.value_of("rpc-url").unwrap(); 75 | 76 | let transport = HttpTransport::new().standalone().unwrap(); 77 | let transport_handle = transport.handle(&rpc_url).unwrap(); 78 | let mut client = NibbleClient::new(transport_handle); 79 | 80 | loop { 81 | print!("> "); 82 | io::stdout().flush().unwrap(); 83 | 84 | let mut input = String::new(); 85 | io::stdin().read_line(&mut input)?; 86 | 87 | let mut args = vec!["nibble"]; 88 | let params = input.trim().split(" "); 89 | args.extend(params); 90 | 91 | match cli.clone().get_matches_from_safe(args) { 92 | Ok(matches) => { 93 | if let Some(_) = matches.subcommand_matches("getpubkey") { 94 | println!("{}", client.getpubkey().call().unwrap()); 95 | } 96 | 97 | if let Some(_) = matches.subcommand_matches("newpubkey") { 98 | println!("{}", client.newpubkey().call().unwrap()); 99 | } 100 | 101 | if let Some(_) = matches.subcommand_matches("mempool") { 102 | println!("{:#?}", client.mempool().call().unwrap()); 103 | } 104 | 105 | if let Some(_) = matches.subcommand_matches("balances") { 106 | let result = client.balances().call().unwrap(); 107 | println!("{}", serde_json::to_string_pretty(&result)?); 108 | } 109 | 110 | if let Some(_) = matches.subcommand_matches("blockheight") { 111 | let result = client.blockheight().call().unwrap(); 112 | println!("{}", result); 113 | } 114 | 115 | if let Some(cmd) = matches.subcommand_matches("getbalance") { 116 | let pubkey = cmd.value_of("pubkey").unwrap(); 117 | let result = client.getbalance(key::PublicKey::from_str(&pubkey).unwrap()).call().unwrap(); 118 | println!("{}", serde_json::to_string_pretty(&result)?); 119 | } 120 | 121 | if let Some(cmd) = matches.subcommand_matches("getblock") { 122 | let block_number: u32 = cmd.value_of("blocknumber").unwrap().parse().unwrap(); 123 | let result = client.getblock(block_number).call().unwrap(); 124 | println!("{}", serde_json::to_string_pretty(&result)?); 125 | } 126 | 127 | if let Some(cmd) = matches.subcommand_matches("send") { 128 | let pubkey = cmd.value_of("pubkey").unwrap(); 129 | let amount : u32 = cmd.value_of("amount").unwrap().parse().unwrap(); 130 | let result = client.send(key::PublicKey::from_str(&pubkey).unwrap(), amount).call().unwrap(); 131 | println!("{}", serde_json::to_string_pretty(&result)?); 132 | } 133 | }, 134 | Err(e) => { 135 | println!("{}", e); 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/node.rs: -------------------------------------------------------------------------------- 1 | use crate::settings; 2 | use crate::block; 3 | use crate::tx; 4 | use crate::crypto; 5 | use crate::storage; 6 | 7 | use crypto::key; 8 | use rocksdb::{DB}; 9 | use colored::*; 10 | use std::fs; 11 | use std::error::Error; 12 | use std::path::Path; 13 | use std::sync::mpsc; 14 | 15 | pub static DIFFICULTY: usize = 2; // TODO: Difficulty adjustment 16 | pub static GENESIS_PREV_BLOCK_HASH: &str = "000000000000000000000000000000000000000000000000000000000000000"; 17 | 18 | pub struct Node { 19 | pub mempool: Vec, 20 | pub keypair: crypto::KeyPair, 21 | 22 | pub db_blocks: DB, 23 | pub db_blocks_metadata: DB, 24 | pub db_balances: DB, 25 | 26 | block_tx: mpsc::Sender, 27 | transaction_tx: mpsc::Sender 28 | } 29 | 30 | impl Node { 31 | fn get_block_reward (&self, block_number: u32) -> u32 { 32 | let halving = block_number / 1000; 33 | if halving >= 10 { return 0 } 34 | return 512 >> halving; 35 | } 36 | 37 | fn create_coinbase_tx (&self) -> Result { 38 | let latest_block_number = storage::get_latest_block_number(&self.db_blocks_metadata)?; 39 | let reward = self.get_block_reward(latest_block_number + 1); 40 | return Ok(tx::create_signed(&self.keypair, self.keypair.public_key, reward)); 41 | } 42 | 43 | fn make_genesis_block (&self) -> Result { 44 | let coinbase_tx = self.create_coinbase_tx()?; 45 | return Ok(block::ProposedBlock { 46 | prev_block: String::from(GENESIS_PREV_BLOCK_HASH), 47 | transactions: vec![coinbase_tx] 48 | }); 49 | } 50 | 51 | fn get_latest_block(&self) -> Result, String> { 52 | let block_hash = match storage::get_latest_block_hash(&self.db_blocks_metadata)? { 53 | Some(block_hash) => block_hash, 54 | None => return Ok(None) 55 | }; 56 | let block = storage::get_block(&self.db_blocks, &block_hash)?; 57 | return Ok(block); 58 | } 59 | 60 | fn verify_block(&self, block: &block::Block) -> Result <(), String> { 61 | if !block.hash.starts_with(&"0".repeat(DIFFICULTY)) { return Err(String::from("Block verification: Must contain correct PoW according to difficulty")) } 62 | 63 | let block_hash = crypto::sha256(block.serialize()); 64 | if hex::encode(block_hash) != block.hash { return Err(String::from("Block verification: Hash must match hash included in block")) } 65 | 66 | let prev_block = self.get_latest_block()?; 67 | let prev_block_hash = prev_block.map_or(String::from(GENESIS_PREV_BLOCK_HASH), |b| b.hash.clone()); 68 | if block.prev_block != prev_block_hash { return Err(String::from("Block verification: Must reference previous block's hash")) } 69 | 70 | let prev_block_number = storage::get_latest_block_number(&self.db_blocks_metadata)?; 71 | 72 | for (i, tx) in block.transactions.iter().enumerate() { 73 | if i == 0 { self.verify_coinbase_tx(&tx, prev_block_number + 1)? } else { self.verify_reg_tx(&tx)? }; 74 | } 75 | 76 | // and many more 77 | 78 | return Ok(()); 79 | } 80 | 81 | fn verify_tx(&self, tx: &tx::SignedTransaction) -> Result <(), String> { 82 | if !tx.is_sig_valid() { return Err(String::from("Transaction verification: Invalid signature")) } 83 | return Ok(()); 84 | } 85 | 86 | fn verify_coinbase_tx(&self, tx: &tx::SignedTransaction, block_number: u32) -> Result <(), String> { 87 | self.verify_tx(&tx)?; 88 | if tx.transaction.amount != self.get_block_reward(block_number) { return Err(String::from("Transaction verification: Coinbase amount not valid")) } 89 | return Ok(()); 90 | } 91 | 92 | fn verify_reg_tx(&self, tx: &tx::SignedTransaction) -> Result <(), String> { 93 | self.verify_tx(&tx)?; 94 | let from_balance = storage::get_balance(&self.db_balances, tx.transaction.from)?.unwrap_or(0); 95 | if from_balance < tx.transaction.amount { return Err(String::from("Transaction verification: Not enough balance")) } 96 | return Ok(()); 97 | } 98 | 99 | fn process_block_transactions(&mut self, block: &block::Block) -> Result<(), String> { 100 | for (i, tx) in block.transactions.iter().enumerate() { 101 | // Coinbase (first tx in block) is allowed to create new supply (by not deducting a balance) 102 | if i > 0 { 103 | let sender_balance = storage::get_balance(&self.db_balances, tx.transaction.from)?.unwrap_or(0); 104 | let sender_new_balance = sender_balance - tx.transaction.amount; 105 | storage::set_balance(&self.db_balances, tx.transaction.from, sender_new_balance)?; 106 | } // Deduct balance 107 | let receiver_balance = storage::get_balance(&self.db_balances, tx.transaction.to)?.unwrap_or(0); 108 | let new_receiver_balance = receiver_balance + tx.transaction.amount; 109 | storage::set_balance(&self.db_balances, tx.transaction.to, new_receiver_balance)?; // Add balance 110 | // Remove processed tx from mempool 111 | let mempool_position = self.mempool.iter().position(|mempool_tx| *mempool_tx.to_string() == tx.to_string()); // TODO: not very efficient, hashmap better suits 112 | if let Some(mempool_position) = mempool_position { 113 | self.mempool.remove(mempool_position); 114 | } 115 | } 116 | return Ok(()); 117 | } 118 | 119 | pub fn process_block(&mut self, block: &block::Block) -> Result<(), String> { 120 | self.verify_block(&block)?; 121 | self.process_block_transactions(&block)?; 122 | let prev_block_number = storage::get_latest_block_number(&self.db_blocks_metadata)?; 123 | storage::add_block(&self.db_blocks, &block)?; 124 | storage::set_latest_block(&self.db_blocks_metadata, &block.hash, prev_block_number + 1)?; 125 | return Ok(()); 126 | } 127 | 128 | pub fn new_transaction (&mut self, tx: &tx::SignedTransaction) -> Result<(), String> { 129 | println!("{} {}={} {}={} {}={} ", 130 | "New Transaction:".green(), 131 | "amount".yellow(), tx.transaction.amount, 132 | "from".yellow(), tx.transaction.from.to_string(), 133 | "to".yellow(), tx.transaction.to.to_string()); 134 | self.verify_reg_tx(&tx)?; 135 | self.mempool.push(tx.clone()); 136 | Ok(()) 137 | } 138 | 139 | pub fn send_transaction (&mut self, public_key: key::PublicKey, amount: u32) -> Result { 140 | let tx = tx::create_signed(&self.keypair, public_key, amount); 141 | self.new_transaction(&tx)?; 142 | self.transaction_tx.send(tx.clone()).unwrap(); 143 | return Ok(tx); 144 | } 145 | 146 | pub fn get_keypair (data_dir: String) -> Result> { 147 | let wallet_path = format!("{}/wallet.key", data_dir); 148 | if Path::new(&wallet_path).exists() { 149 | let key = fs::read_to_string(wallet_path)?; 150 | return Ok(crypto::KeyPair::from(key)?); 151 | } 152 | 153 | let keypair = crypto::KeyPair::new(); 154 | fs::write(&wallet_path, keypair.private_key.to_string())?; 155 | return Ok(keypair); 156 | } 157 | 158 | pub fn start (&mut self) -> Result, String> { 159 | return self.get_latest_block(); 160 | } 161 | 162 | pub fn get_proposed_block (&mut self) -> Result { 163 | let prev_block = self.get_latest_block().expect("Previous block does not exist"); 164 | return match prev_block { 165 | Some(prev_block) => { 166 | let mut txs = vec![self.create_coinbase_tx()?]; 167 | txs.extend(self.mempool.clone()); 168 | Ok(block::ProposedBlock { 169 | prev_block: prev_block.hash.clone(), 170 | transactions: txs, 171 | }) 172 | }, 173 | None => { 174 | println!("Initiating Genesis Block"); 175 | Ok(self.make_genesis_block()?) 176 | } 177 | } 178 | } 179 | 180 | pub fn receive_block (&mut self, block: block::Block) -> Result<(), String> { 181 | self.process_block(&block)?; 182 | self.block_tx.send(block).unwrap(); 183 | return Ok(()); 184 | } 185 | 186 | pub fn new (block_tx: mpsc::Sender, transaction_tx: mpsc::Sender) -> Node { 187 | let config = settings::Settings::new().unwrap(); 188 | fs::create_dir_all(config.data_dir.clone()).expect("Could not create data dir"); 189 | return Node { 190 | keypair: Node::get_keypair(config.data_dir).expect("Could not load wallet"), 191 | mempool: Vec::new(), 192 | db_blocks: storage::db::blocks(false), 193 | db_blocks_metadata: storage::db::blocks_md(false), 194 | db_balances: storage::db::balances(false), 195 | block_tx, 196 | transaction_tx 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /web/public/build/bundle.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "bundle.css", 4 | "sources": [ 5 | "App.svelte", 6 | "Explorer.svelte", 7 | "Wallet.svelte" 8 | ], 9 | "sourcesContent": [ 10 | "\n\n\n\n
\n\t

NIBBLE

\n\t
\n\t\tNode: \n\t
\n\t\n\t\n
\n", 11 | "\n\n\n\n
\n

Mempool

\n
\n {#if mempool.length}\n \n \n \n \n \n \n {#each mempool as item}\n \n \n \n \n \n {/each}\n
FromToValue
{item.transaction.from}{item.transaction.to}{item.transaction.amount}
\n {:else}\n Empty\n {/if}\n
\n
\n

Blocks

\n
\n
\n {#each blocks.slice().reverse() as block (block)}\n \n {/each}\n
\n {#if selectedBlock}\n
\n

{selectedBlock.hash}

\n \n \n \n \n \n \n {#each selectedBlock.transactions as item}\n \n \n \n \n \n {/each}\n
FromToValue
{item.transaction.from}{item.transaction.to}{item.transaction.amount}
\n
\n {/if}\n
\n
", 12 | "\n\n\n\n
\n

Wallet

\n
\n
Balance:
{#await balance then balance}{balance} Nibble {/await}
\n
Public Key:
{#await pubKey then pubKey}{/await}
\n
\n
\n

Send

\n
\n
To:
\n
Amount:
\n
\n
\n

Random Public Key

\n
{#await randomPubKey then randomPubKey}{/await}
\n
\n

Get Balance

\n
\n
Public Key:
\n {#if !isNaN(pubKeyBalance)}{pubKeyBalance} Nibble{/if}\n
\n
" 13 | ], 14 | "names": [], 15 | "mappings": "AAQA,UAAU,cAAC,CAAC,AACX,KAAK,CAAE,MAAM,CACb,MAAM,CAAE,CAAC,CAAC,IAAI,CACd,OAAO,CAAE,IAAI,CACb,qBAAqB,CAAE,GAAG,CAAC,GAAG,CAC9B,kBAAkB,CAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAClC,mBAAmB,CACZ,YAAY;QACZ,iBAAiB,AACzB,CAAC,AAED,EAAE,cAAC,CAAC,AACH,KAAK,CAAE,OAAO,CACd,SAAS,CAAE,MAAM,AAClB,CAAC,AAED,IAAI,cAAC,CAAC,AACL,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,KAAK,CACjB,UAAU,CAAE,MAAM,AACnB,CAAC;ACeG,SAAS,8BAAC,CAAC,AACP,OAAO,CAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACzB,WAAW,CAAE,IAAI,CACjB,MAAM,CAAE,GAAG,CAAC,KAAK,CAAC,OAAO,AAC7B,CAAC,AAED,MAAM,8BAAC,CAAC,AACJ,KAAK,CAAE,IAAI,CACX,YAAY,CAAE,KAAK,CACnB,eAAe,CAAE,QAAQ,AAC7B,CAAC,AAED,qBAAM,CAAC,oBAAK,CAAE,qBAAM,CAAC,EAAE,eAAC,CAAC,AACrB,aAAa,CAAE,GAAG,CAAC,KAAK,CAAC,OAAO,AACpC,CAAC,AAED,qBAAM,CAAC,EAAE,eAAC,CAAC,AACP,WAAW,CAAE,IAAI,CACjB,aAAa,CAAE,IAAI,AACvB,CAAC,AAED,qBAAM,CAAC,KAAK,eAAC,CAAC,AACV,WAAW,CAAE,IAAI,AACrB,CAAC,AAED,qBAAM,CAAC,KAAK,CAAC,iBAAE,WAAW,CAAC,CAAC,AAAC,CAAC,AAC1B,KAAK,CAAE,KAAK,AAChB,CAAC,AAED,qBAAM,CAAC,EAAE,eAAC,CAAC,AACP,cAAc,CAAE,IAAI,AACxB,CAAC,AAED,qBAAM,CAAC,EAAE,CAAC,EAAE,eAAC,CAAC,AACV,QAAQ,CAAE,MAAM,CAChB,aAAa,CAAE,QAAQ,AAC3B,CAAC,AAED,qBAAM,CAAC,EAAE,CAAC,iBAAE,MAAM,AAAC,CAAC,AAChB,QAAQ,CAAE,IAAI,CACd,aAAa,CAAE,OAAO,CACtB,aAAa,CAAE,UAAU,AAC7B,CAAC,AAED,OAAO,8BAAC,CAAC,AACL,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,AACvB,CAAC,AAED,WAAW,8BAAC,CAAC,AACT,WAAW,CAAE,MAAM,CACnB,MAAM,CAAE,KAAK,CACb,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,IAAI,AACvB,CAAC,AAED,0BAAW,CAAC,MAAM,eAAC,CAAC,AAChB,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CACtB,aAAa,CAAE,IAAI,AACvB,CAAC,AAED,aAAa,8BAAC,CAAC,AACX,IAAI,CAAE,CAAC,CACP,YAAY,CAAE,IAAI,AACtB,CAAC;AC3DD,OAAO,cAAC,CAAC,AACL,OAAO,CAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACzB,MAAM,CAAE,GAAG,CAAC,KAAK,CAAC,OAAO,AAC7B,CAAC,AAED,KAAK,cAAC,CAAC,AACH,OAAO,CAAE,IAAI,CACb,kBAAkB,CAAE,IAAI,CAAC,IAAI,CAC7B,qBAAqB,CAAE,IAAI,CAAC,GAAG,CAC/B,QAAQ,CAAE,IAAI,CACd,WAAW,CAAE,MAAM,AACvB,CAAC" 16 | } -------------------------------------------------------------------------------- /src/p2p.rs: -------------------------------------------------------------------------------- 1 | use crate::storage; 2 | use crate::block; 3 | use crate::tx; 4 | use crate::node; 5 | 6 | use colored::*; 7 | use std::error; 8 | use std::io::prelude::*; 9 | use std::net::TcpListener; 10 | use std::net::TcpStream; 11 | use std::sync::{Arc, Mutex}; 12 | use std::sync::mpsc; 13 | use std::thread; 14 | use std::time; 15 | use regex::Regex; 16 | 17 | const MESSAGE_NEW_PEER: &str = "NEW_PEER"; 18 | const MESSAGE_PING: &str = "PING"; 19 | 20 | const MESSAGE_GET_BLOCK: &str = "GET_BLOCK"; 21 | const MESSAGE_GET_BLOCKS: &str = "GET_BLOCKS"; 22 | 23 | const MESSAGE_NEW_BLOCK: &str = "NEW_BLOCK"; 24 | const MESSAGE_NEW_TRANSACTION: &str = "NEW_TRANSACTION"; 25 | 26 | pub struct P2PData { 27 | peers: Vec, 28 | } 29 | 30 | impl P2PData { 31 | pub fn new() -> Self { 32 | return Self { 33 | peers: vec![], 34 | } 35 | } 36 | } 37 | 38 | struct P2PServer { 39 | node_ref: Arc>, 40 | p2p_data_ref: Arc>, 41 | host_addr: String, 42 | miner_interrupt_tx: mpsc::Sender<()> 43 | } 44 | 45 | impl P2PServer { 46 | fn handle_get_blocks (&mut self) -> Result { 47 | let block_hashes = storage::get_block_hashes(&storage::db::blocks_md(true))?; 48 | return Ok(serde_json::to_string(&block_hashes).unwrap()); 49 | } 50 | 51 | fn handle_get_block (&mut self, block_hash: String) -> Result { 52 | let block = storage::get_block(&storage::db::blocks(true), &block_hash)?; 53 | return Ok(serde_json::to_string_pretty(&block).unwrap()); 54 | } 55 | 56 | fn handle_new_block (&mut self, block: String) -> Result { 57 | // TODO: fork resolution (heaviest chain) 58 | let block: block::Block = serde_json::from_str(&block).unwrap(); 59 | let mut node = self.node_ref.lock().unwrap(); 60 | let existing_block = storage::get_block(&storage::db::blocks(true), &block.hash)?; 61 | if let None = existing_block { 62 | println!("{} {} - TXs: {}", "New Block:".green(), block.hash, block.transactions.len()); 63 | node.process_block(&block)?; 64 | self.miner_interrupt_tx.send(()).unwrap(); 65 | } 66 | return Ok(String::from("OK")); 67 | } 68 | 69 | fn handle_new_transaction (&mut self, tx: String) -> Result { 70 | let tx: tx::SignedTransaction = serde_json::from_str(&tx).unwrap(); 71 | let mut node = self.node_ref.lock().unwrap(); 72 | // TODO: Check if tx is duplicate 73 | node.new_transaction(&tx)?; 74 | return Ok(String::from("OK")); 75 | } 76 | 77 | fn handle_new_peer (&mut self, peer: String) -> Result > { 78 | add_peer(self.node_ref.clone(), self.p2p_data_ref.clone(), self.miner_interrupt_tx.clone(), peer.clone())?; 79 | let p2p_data = self.p2p_data_ref.lock().unwrap(); 80 | let resp_peers: Vec = p2p_data.peers.clone().into_iter().filter(|x| *x != peer).collect(); 81 | return Ok(serde_json::to_string(&resp_peers)?); 82 | } 83 | 84 | fn handle_connection(&mut self, mut stream: TcpStream) -> Result<(), Box> { 85 | let mut buffer = [0; 100000]; 86 | 87 | stream.read(&mut buffer)?; 88 | 89 | let msg_raw = String::from_utf8_lossy(&buffer[..]); 90 | let msg = msg_raw.as_ref(); 91 | 92 | let response = if msg.starts_with(MESSAGE_PING) { 93 | String::from("OK") 94 | } else if msg.starts_with(MESSAGE_GET_BLOCKS) { 95 | let block_hashes = self.handle_get_blocks()?; 96 | block_hashes 97 | } else if msg.starts_with(MESSAGE_GET_BLOCK) { 98 | let re = Regex::new(&format!(r"{}\((?P.*?)\)", MESSAGE_GET_BLOCK))?; 99 | let caps = re.captures(msg).unwrap(); 100 | let block_hash = &caps["hash"]; 101 | self.handle_get_block(block_hash.to_string())? 102 | } else if msg.starts_with(MESSAGE_NEW_BLOCK) { 103 | let re = Regex::new(&format!(r"{}\((?P.*?)\)", MESSAGE_NEW_BLOCK))?; 104 | let caps = re.captures(msg).unwrap(); 105 | let block = &caps["block"]; 106 | self.handle_new_block(block.to_string())? 107 | } else if msg.starts_with(MESSAGE_NEW_PEER) { 108 | let re = Regex::new(&format!(r"{}\((?P.*?)\)", MESSAGE_NEW_PEER))?; 109 | let caps = re.captures(msg).unwrap(); 110 | let host = &caps["host"]; 111 | self.handle_new_peer(host.to_string())? 112 | } else if msg.starts_with(MESSAGE_NEW_TRANSACTION) { 113 | let re = Regex::new(&format!(r"{}\((?P.*?)\)", MESSAGE_NEW_TRANSACTION))?; 114 | let caps = re.captures(msg).unwrap(); 115 | let tx = &caps["tx"]; 116 | self.handle_new_transaction(tx.to_string())? 117 | } else { 118 | String::from("UNRECOGNIZED MESSAGE") 119 | }; 120 | 121 | let final_response = format!("{}\r\n", response); 122 | 123 | stream.write(final_response.as_bytes())?; 124 | stream.flush()?; 125 | 126 | return Ok(()); 127 | } 128 | 129 | pub fn run (&mut self) -> Result<(), Box> { 130 | let listener = TcpListener::bind(&self.host_addr)?; 131 | 132 | println!("{} Listening on {}", "P2P:".green(), listener.local_addr()?.to_string()); 133 | 134 | for stream in listener.incoming() { 135 | self.handle_connection(stream?)?; 136 | } 137 | 138 | Ok(()) 139 | } 140 | } 141 | 142 | pub fn run_server(node_ref: Arc>, p2p_data_ref: Arc>, host_addr: String, miner_interrupt_tx: mpsc::Sender<()>) -> Result<(), Box> { 143 | let mut server = P2PServer { 144 | node_ref, 145 | p2p_data_ref, 146 | host_addr, 147 | miner_interrupt_tx 148 | }; 149 | 150 | server.run()?; 151 | 152 | Ok(()) 153 | } 154 | 155 | fn send (peer: &String, req: String, data: Option) -> Result> { 156 | let mut stream = TcpStream::connect(peer)?; 157 | 158 | let msg = match data { 159 | Some(data) => format!("{}({})", req, data), 160 | None => req 161 | }; 162 | 163 | stream.write(&msg.as_bytes())?; 164 | let mut buffer = [0; 100000]; 165 | stream.read(&mut buffer)?; 166 | 167 | let response_raw = String::from_utf8_lossy(&buffer[..]); 168 | let response_parts: Vec<&str> = response_raw.split("\r\n").collect(); 169 | let response = response_parts[0].to_string(); 170 | 171 | Ok(response) 172 | } 173 | 174 | pub fn add_peer(node_ref: Arc>, p2p_data_ref: Arc>, miner_interrupt_tx: mpsc::Sender<()>, addr: String) -> Result<(), Box> { 175 | let mut p2p_data = p2p_data_ref.lock().unwrap(); 176 | if !p2p_data.peers.contains(&addr) { 177 | println!("{} {}", "New Peer:".green(), addr); 178 | p2p_data.peers.push(addr.clone()); 179 | check_peer_blocks(node_ref, miner_interrupt_tx, addr.clone())?; // Doesn't seem right that adding new peer needs to immediately check blocks 180 | } 181 | Ok(()) 182 | } 183 | 184 | pub fn init_node_list(node_ref: Arc>, p2p_data_ref: Arc>, miner_interrupt_tx: mpsc::Sender<()>, bootstrap_node: String, self_addr: String) -> Result<(), Box> { 185 | add_peer(node_ref.clone(), p2p_data_ref.clone(), miner_interrupt_tx.clone(), bootstrap_node.clone())?; 186 | let resp = send(&bootstrap_node, MESSAGE_NEW_PEER.to_string(), Some(self_addr.clone()))?; // TODO: proper address 187 | let peers: Vec = serde_json::from_str(&resp)?; 188 | for peer in peers { 189 | add_peer(node_ref.clone(), p2p_data_ref.clone(), miner_interrupt_tx.clone(), peer.to_string())?; 190 | send(&peer, MESSAGE_NEW_PEER.to_string(), Some(self_addr.clone()))?; 191 | } 192 | Ok(()) 193 | } 194 | 195 | pub fn check_peer_blocks(node_ref: Arc>, miner_interrupt_tx: mpsc::Sender<()>, peer: String) -> Result<(), Box> { 196 | let blocks_resp = send(&peer, MESSAGE_GET_BLOCKS.to_string(), None)?; 197 | let block_hashes: Vec = serde_json::from_str(&blocks_resp)?; 198 | 199 | let missing_hashes = match storage::get_latest_block_hash(&storage::db::blocks_md(true))? { 200 | Some(latest_block_hash) => { 201 | let position = block_hashes.iter().position(|x| *x == latest_block_hash); 202 | match position { 203 | Some(position) => block_hashes[(position + 1)..].to_vec(), 204 | None => vec![] 205 | } 206 | }, 207 | None => { 208 | block_hashes 209 | } 210 | }; 211 | 212 | for block_hash in missing_hashes { 213 | let block_raw = send(&peer, MESSAGE_GET_BLOCK.to_string(), Some(block_hash))?; 214 | let block: block::Block = serde_json::from_str(&block_raw)?; 215 | let mut node = node_ref.lock().unwrap(); 216 | node.process_block(&block)?; 217 | miner_interrupt_tx.send(()).unwrap(); 218 | } 219 | 220 | Ok(()) 221 | } 222 | 223 | pub fn init(node_ref: Arc>, p2p_data_ref: Arc>, miner_interrupt_tx: mpsc::Sender<()>, host_addr: String, bootstrap_node: Option) -> Result<(), Box> { 224 | match bootstrap_node { 225 | Some(bootstrap_node) => { 226 | init_node_list(node_ref.clone(), p2p_data_ref.clone(), miner_interrupt_tx, bootstrap_node, host_addr)?; 227 | }, 228 | _ => () 229 | } 230 | 231 | Ok(()) 232 | } 233 | 234 | pub fn check_peers (p2p_data_ref: Arc>) { 235 | let mut p2p_data = p2p_data_ref.lock().unwrap(); 236 | p2p_data.peers.retain(|peer| if let Err(e) = send(peer, MESSAGE_PING.to_string(), None) { println!("Disconnected ({}) - {:?}", peer, e); return false; } else { return true }); 237 | } 238 | 239 | pub fn publish (p2p_data_ref: Arc>, req: String, data: String) -> Result<(), Box> { 240 | let p2p_data = p2p_data_ref.lock().unwrap(); 241 | for peer in &p2p_data.peers { 242 | if let Err(_e) = send(peer, req.clone(), Some(data.clone())) { 243 | println!("{}", format!("Failed to publish to peer: {}", peer).red()); 244 | } 245 | } 246 | Ok(()) 247 | } 248 | 249 | pub fn publish_block(p2p_data_ref: Arc>, block: block::Block) -> Result<(), Box> { 250 | publish(p2p_data_ref, MESSAGE_NEW_BLOCK.to_string(), serde_json::to_string(&block)?) 251 | } 252 | 253 | pub fn publish_tx(p2p_data_ref: Arc>, tx: tx::SignedTransaction) -> Result<(), Box> { 254 | publish(p2p_data_ref, MESSAGE_NEW_TRANSACTION.to_string(), serde_json::to_string(&tx)?) 255 | } 256 | 257 | pub fn run_receiver (p2p_data_ref: Arc>, block_rx: mpsc::Receiver, transaction_rx: mpsc::Receiver) { 258 | let mut now = time::Instant::now(); 259 | loop { 260 | // TODO: keep trying to reconnect to bootstrap nodes if they go offline 261 | if now.elapsed().as_secs() > 60 { 262 | check_peers(p2p_data_ref.clone()); 263 | now = time::Instant::now(); 264 | } 265 | 266 | if let Ok(block) = block_rx.try_recv() { 267 | publish_block(p2p_data_ref.clone(), block).unwrap(); 268 | } 269 | if let Ok(tx) = transaction_rx.try_recv() { 270 | publish_tx(p2p_data_ref.clone(), tx).unwrap(); 271 | } 272 | thread::sleep(time::Duration::from_millis(100)); 273 | } 274 | } -------------------------------------------------------------------------------- /web/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | } 32 | }, 33 | "@polka/url": { 34 | "version": "1.0.0-next.11", 35 | "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", 36 | "integrity": "sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA==" 37 | }, 38 | "@rollup/plugin-commonjs": { 39 | "version": "14.0.0", 40 | "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-14.0.0.tgz", 41 | "integrity": "sha512-+PSmD9ePwTAeU106i9FRdc+Zb3XUWyW26mo5Atr2mk82hor8+nPwkztEjFo8/B1fJKfaQDg9aM2bzQkjhi7zOw==", 42 | "dev": true, 43 | "requires": { 44 | "@rollup/pluginutils": "^3.0.8", 45 | "commondir": "^1.0.1", 46 | "estree-walker": "^1.0.1", 47 | "glob": "^7.1.2", 48 | "is-reference": "^1.1.2", 49 | "magic-string": "^0.25.2", 50 | "resolve": "^1.11.0" 51 | } 52 | }, 53 | "@rollup/plugin-node-resolve": { 54 | "version": "8.4.0", 55 | "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.4.0.tgz", 56 | "integrity": "sha512-LFqKdRLn0ShtQyf6SBYO69bGE1upV6wUhBX0vFOUnLAyzx5cwp8svA0eHUnu8+YU57XOkrMtfG63QOpQx25pHQ==", 57 | "dev": true, 58 | "requires": { 59 | "@rollup/pluginutils": "^3.1.0", 60 | "@types/resolve": "1.17.1", 61 | "builtin-modules": "^3.1.0", 62 | "deep-freeze": "^0.0.1", 63 | "deepmerge": "^4.2.2", 64 | "is-module": "^1.0.0", 65 | "resolve": "^1.17.0" 66 | } 67 | }, 68 | "@rollup/pluginutils": { 69 | "version": "3.1.0", 70 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 71 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 72 | "dev": true, 73 | "requires": { 74 | "@types/estree": "0.0.39", 75 | "estree-walker": "^1.0.1", 76 | "picomatch": "^2.2.2" 77 | } 78 | }, 79 | "@types/estree": { 80 | "version": "0.0.39", 81 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 82 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 83 | "dev": true 84 | }, 85 | "@types/node": { 86 | "version": "14.10.1", 87 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.10.1.tgz", 88 | "integrity": "sha512-aYNbO+FZ/3KGeQCEkNhHFRIzBOUgc7QvcVNKXbfnhDkSfwUv91JsQQa10rDgKSTSLkXZ1UIyPe4FJJNVgw1xWQ==", 89 | "dev": true 90 | }, 91 | "@types/resolve": { 92 | "version": "1.17.1", 93 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", 94 | "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", 95 | "dev": true, 96 | "requires": { 97 | "@types/node": "*" 98 | } 99 | }, 100 | "ansi-styles": { 101 | "version": "3.2.1", 102 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 103 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 104 | "dev": true, 105 | "requires": { 106 | "color-convert": "^1.9.0" 107 | } 108 | }, 109 | "anymatch": { 110 | "version": "3.1.1", 111 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 112 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 113 | "dev": true, 114 | "requires": { 115 | "normalize-path": "^3.0.0", 116 | "picomatch": "^2.0.4" 117 | } 118 | }, 119 | "async-limiter": { 120 | "version": "1.0.1", 121 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 122 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", 123 | "dev": true 124 | }, 125 | "balanced-match": { 126 | "version": "1.0.0", 127 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 128 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 129 | "dev": true 130 | }, 131 | "binary-extensions": { 132 | "version": "2.1.0", 133 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", 134 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", 135 | "dev": true 136 | }, 137 | "brace-expansion": { 138 | "version": "1.1.11", 139 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 140 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 141 | "dev": true, 142 | "requires": { 143 | "balanced-match": "^1.0.0", 144 | "concat-map": "0.0.1" 145 | } 146 | }, 147 | "braces": { 148 | "version": "3.0.2", 149 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 150 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 151 | "dev": true, 152 | "requires": { 153 | "fill-range": "^7.0.1" 154 | } 155 | }, 156 | "buffer-from": { 157 | "version": "1.1.1", 158 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 159 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 160 | "dev": true 161 | }, 162 | "builtin-modules": { 163 | "version": "3.1.0", 164 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", 165 | "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", 166 | "dev": true 167 | }, 168 | "chalk": { 169 | "version": "2.4.2", 170 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 171 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 172 | "dev": true, 173 | "requires": { 174 | "ansi-styles": "^3.2.1", 175 | "escape-string-regexp": "^1.0.5", 176 | "supports-color": "^5.3.0" 177 | } 178 | }, 179 | "chokidar": { 180 | "version": "3.4.2", 181 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", 182 | "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", 183 | "dev": true, 184 | "requires": { 185 | "anymatch": "~3.1.1", 186 | "braces": "~3.0.2", 187 | "fsevents": "~2.1.2", 188 | "glob-parent": "~5.1.0", 189 | "is-binary-path": "~2.1.0", 190 | "is-glob": "~4.0.1", 191 | "normalize-path": "~3.0.0", 192 | "readdirp": "~3.4.0" 193 | } 194 | }, 195 | "color-convert": { 196 | "version": "1.9.3", 197 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 198 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 199 | "dev": true, 200 | "requires": { 201 | "color-name": "1.1.3" 202 | } 203 | }, 204 | "color-name": { 205 | "version": "1.1.3", 206 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 207 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 208 | "dev": true 209 | }, 210 | "commander": { 211 | "version": "2.20.3", 212 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 213 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 214 | "dev": true 215 | }, 216 | "commondir": { 217 | "version": "1.0.1", 218 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 219 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 220 | "dev": true 221 | }, 222 | "concat-map": { 223 | "version": "0.0.1", 224 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 225 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 226 | "dev": true 227 | }, 228 | "console-clear": { 229 | "version": "1.1.1", 230 | "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", 231 | "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==" 232 | }, 233 | "deep-freeze": { 234 | "version": "0.0.1", 235 | "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", 236 | "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=", 237 | "dev": true 238 | }, 239 | "deepmerge": { 240 | "version": "4.2.2", 241 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", 242 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", 243 | "dev": true 244 | }, 245 | "escape-string-regexp": { 246 | "version": "1.0.5", 247 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 248 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 249 | "dev": true 250 | }, 251 | "estree-walker": { 252 | "version": "1.0.1", 253 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 254 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 255 | "dev": true 256 | }, 257 | "fill-range": { 258 | "version": "7.0.1", 259 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 260 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 261 | "dev": true, 262 | "requires": { 263 | "to-regex-range": "^5.0.1" 264 | } 265 | }, 266 | "fs.realpath": { 267 | "version": "1.0.0", 268 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 269 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 270 | "dev": true 271 | }, 272 | "fsevents": { 273 | "version": "2.1.3", 274 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 275 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 276 | "dev": true, 277 | "optional": true 278 | }, 279 | "get-port": { 280 | "version": "3.2.0", 281 | "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", 282 | "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" 283 | }, 284 | "glob": { 285 | "version": "7.1.6", 286 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 287 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 288 | "dev": true, 289 | "requires": { 290 | "fs.realpath": "^1.0.0", 291 | "inflight": "^1.0.4", 292 | "inherits": "2", 293 | "minimatch": "^3.0.4", 294 | "once": "^1.3.0", 295 | "path-is-absolute": "^1.0.0" 296 | } 297 | }, 298 | "glob-parent": { 299 | "version": "5.1.1", 300 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 301 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 302 | "dev": true, 303 | "requires": { 304 | "is-glob": "^4.0.1" 305 | } 306 | }, 307 | "has-flag": { 308 | "version": "3.0.0", 309 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 310 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 311 | "dev": true 312 | }, 313 | "inflight": { 314 | "version": "1.0.6", 315 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 316 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 317 | "dev": true, 318 | "requires": { 319 | "once": "^1.3.0", 320 | "wrappy": "1" 321 | } 322 | }, 323 | "inherits": { 324 | "version": "2.0.4", 325 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 326 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 327 | "dev": true 328 | }, 329 | "is-binary-path": { 330 | "version": "2.1.0", 331 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 332 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 333 | "dev": true, 334 | "requires": { 335 | "binary-extensions": "^2.0.0" 336 | } 337 | }, 338 | "is-extglob": { 339 | "version": "2.1.1", 340 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 341 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 342 | "dev": true 343 | }, 344 | "is-glob": { 345 | "version": "4.0.1", 346 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 347 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 348 | "dev": true, 349 | "requires": { 350 | "is-extglob": "^2.1.1" 351 | } 352 | }, 353 | "is-module": { 354 | "version": "1.0.0", 355 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", 356 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", 357 | "dev": true 358 | }, 359 | "is-number": { 360 | "version": "7.0.0", 361 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 362 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 363 | "dev": true 364 | }, 365 | "is-reference": { 366 | "version": "1.2.1", 367 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", 368 | "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", 369 | "dev": true, 370 | "requires": { 371 | "@types/estree": "*" 372 | } 373 | }, 374 | "jest-worker": { 375 | "version": "26.3.0", 376 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", 377 | "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", 378 | "dev": true, 379 | "requires": { 380 | "@types/node": "*", 381 | "merge-stream": "^2.0.0", 382 | "supports-color": "^7.0.0" 383 | }, 384 | "dependencies": { 385 | "has-flag": { 386 | "version": "4.0.0", 387 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 388 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 389 | "dev": true 390 | }, 391 | "supports-color": { 392 | "version": "7.2.0", 393 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 394 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 395 | "dev": true, 396 | "requires": { 397 | "has-flag": "^4.0.0" 398 | } 399 | } 400 | } 401 | }, 402 | "js-tokens": { 403 | "version": "4.0.0", 404 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 405 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 406 | "dev": true 407 | }, 408 | "kleur": { 409 | "version": "3.0.3", 410 | "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", 411 | "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" 412 | }, 413 | "livereload": { 414 | "version": "0.9.1", 415 | "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.1.tgz", 416 | "integrity": "sha512-9g7sua11kkyZNo2hLRCG3LuZZwqexoyEyecSlV8cAsfAVVCZqLzVir6XDqmH0r+Vzgnd5LrdHDMyjtFnJQLAYw==", 417 | "dev": true, 418 | "requires": { 419 | "chokidar": "^3.3.0", 420 | "livereload-js": "^3.1.0", 421 | "opts": ">= 1.2.0", 422 | "ws": "^6.2.1" 423 | } 424 | }, 425 | "livereload-js": { 426 | "version": "3.3.1", 427 | "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.1.tgz", 428 | "integrity": "sha512-CBu1gTEfzVhlOK1WASKAAJ9Qx1fHECTq0SUB67sfxwQssopTyvzqTlgl+c0h9pZ6V+Fzd2rc510ppuNusg9teQ==", 429 | "dev": true 430 | }, 431 | "local-access": { 432 | "version": "1.0.1", 433 | "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.0.1.tgz", 434 | "integrity": "sha512-ykt2pgN0aqIy6KQC1CqdWTWkmUwNgaOS6dcpHVjyBJONA+Xi7AtSB1vuxC/U/0tjIP3wcRudwQk1YYzUvzk2bA==" 435 | }, 436 | "magic-string": { 437 | "version": "0.25.7", 438 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", 439 | "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", 440 | "dev": true, 441 | "requires": { 442 | "sourcemap-codec": "^1.4.4" 443 | } 444 | }, 445 | "merge-stream": { 446 | "version": "2.0.0", 447 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 448 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 449 | "dev": true 450 | }, 451 | "mime": { 452 | "version": "2.4.6", 453 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", 454 | "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" 455 | }, 456 | "minimatch": { 457 | "version": "3.0.4", 458 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 459 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 460 | "dev": true, 461 | "requires": { 462 | "brace-expansion": "^1.1.7" 463 | } 464 | }, 465 | "mri": { 466 | "version": "1.1.6", 467 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", 468 | "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" 469 | }, 470 | "normalize-path": { 471 | "version": "3.0.0", 472 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 473 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 474 | "dev": true 475 | }, 476 | "once": { 477 | "version": "1.4.0", 478 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 479 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 480 | "dev": true, 481 | "requires": { 482 | "wrappy": "1" 483 | } 484 | }, 485 | "opts": { 486 | "version": "2.0.2", 487 | "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", 488 | "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", 489 | "dev": true 490 | }, 491 | "path-is-absolute": { 492 | "version": "1.0.1", 493 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 494 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 495 | "dev": true 496 | }, 497 | "path-parse": { 498 | "version": "1.0.6", 499 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 500 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 501 | "dev": true 502 | }, 503 | "picomatch": { 504 | "version": "2.2.2", 505 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 506 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 507 | "dev": true 508 | }, 509 | "randombytes": { 510 | "version": "2.1.0", 511 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 512 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 513 | "dev": true, 514 | "requires": { 515 | "safe-buffer": "^5.1.0" 516 | } 517 | }, 518 | "readdirp": { 519 | "version": "3.4.0", 520 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", 521 | "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", 522 | "dev": true, 523 | "requires": { 524 | "picomatch": "^2.2.1" 525 | } 526 | }, 527 | "require-relative": { 528 | "version": "0.8.7", 529 | "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", 530 | "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", 531 | "dev": true 532 | }, 533 | "resolve": { 534 | "version": "1.17.0", 535 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", 536 | "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", 537 | "dev": true, 538 | "requires": { 539 | "path-parse": "^1.0.6" 540 | } 541 | }, 542 | "rollup": { 543 | "version": "2.26.11", 544 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.11.tgz", 545 | "integrity": "sha512-xyfxxhsE6hW57xhfL1I+ixH8l2bdoIMaAecdQiWF3N7IgJEMu99JG+daBiSZQjnBpzFxa0/xZm+3pbCdAQehHw==", 546 | "dev": true, 547 | "requires": { 548 | "fsevents": "~2.1.2" 549 | } 550 | }, 551 | "rollup-plugin-livereload": { 552 | "version": "2.0.0", 553 | "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.0.tgz", 554 | "integrity": "sha512-oC/8NqumGYuphkqrfszOHUUIwzKsaHBICw6QRwT5uD07gvePTS+HW+GFwu6f9K8W02CUuTvtIM9AWJrbj4wE1A==", 555 | "dev": true, 556 | "requires": { 557 | "livereload": "^0.9.1" 558 | } 559 | }, 560 | "rollup-plugin-svelte": { 561 | "version": "6.0.1", 562 | "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.0.1.tgz", 563 | "integrity": "sha512-kS9/JZMBNgpKTqVKlwV8mhmGwxu8NiNf6+n5ZzdZ8yDp3+ADqjf8Au+JNEpoOn6kLlh1hLS2Gsa76k9RP57HDQ==", 564 | "dev": true, 565 | "requires": { 566 | "require-relative": "^0.8.7", 567 | "rollup-pluginutils": "^2.8.2", 568 | "sourcemap-codec": "^1.4.8" 569 | } 570 | }, 571 | "rollup-plugin-terser": { 572 | "version": "7.0.2", 573 | "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", 574 | "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", 575 | "dev": true, 576 | "requires": { 577 | "@babel/code-frame": "^7.10.4", 578 | "jest-worker": "^26.2.1", 579 | "serialize-javascript": "^4.0.0", 580 | "terser": "^5.0.0" 581 | } 582 | }, 583 | "rollup-pluginutils": { 584 | "version": "2.8.2", 585 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", 586 | "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", 587 | "dev": true, 588 | "requires": { 589 | "estree-walker": "^0.6.1" 590 | }, 591 | "dependencies": { 592 | "estree-walker": { 593 | "version": "0.6.1", 594 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 595 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 596 | "dev": true 597 | } 598 | } 599 | }, 600 | "sade": { 601 | "version": "1.7.3", 602 | "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.3.tgz", 603 | "integrity": "sha512-m4BctppMvJ60W1dXnHq7jMmFe3hPJZDAH85kQ3ACTo7XZNVUuTItCQ+2HfyaMeV5cKrbw7l4vD/6We3GBxvdJw==", 604 | "requires": { 605 | "mri": "^1.1.0" 606 | } 607 | }, 608 | "safe-buffer": { 609 | "version": "5.2.1", 610 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 611 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 612 | "dev": true 613 | }, 614 | "semiver": { 615 | "version": "1.1.0", 616 | "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", 617 | "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==" 618 | }, 619 | "serialize-javascript": { 620 | "version": "4.0.0", 621 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", 622 | "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", 623 | "dev": true, 624 | "requires": { 625 | "randombytes": "^2.1.0" 626 | } 627 | }, 628 | "sirv": { 629 | "version": "1.0.6", 630 | "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.6.tgz", 631 | "integrity": "sha512-LRGu7Op4Xl9hhigOy2kcB53zAYTjNDdpooey49dIU0cMdpOv9ithVf7nstk3jvs8EhMiT/VORoyazZYGgw4vnA==", 632 | "requires": { 633 | "@polka/url": "^1.0.0-next.9", 634 | "mime": "^2.3.1", 635 | "totalist": "^1.0.0" 636 | } 637 | }, 638 | "sirv-cli": { 639 | "version": "1.0.6", 640 | "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.6.tgz", 641 | "integrity": "sha512-K/iY1OHG7hTw4GzLoqMhwzKCbgWmx5joYAAF2+CwyiamWCpVzAgNVWgAc0JmSA2Gf3wseov05il2QbFTGTZMVg==", 642 | "requires": { 643 | "console-clear": "^1.1.0", 644 | "get-port": "^3.2.0", 645 | "kleur": "^3.0.0", 646 | "local-access": "^1.0.1", 647 | "sade": "^1.6.0", 648 | "semiver": "^1.0.0", 649 | "sirv": "^1.0.6", 650 | "tinydate": "^1.0.0" 651 | } 652 | }, 653 | "source-map": { 654 | "version": "0.6.1", 655 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 656 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 657 | "dev": true 658 | }, 659 | "source-map-support": { 660 | "version": "0.5.19", 661 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 662 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 663 | "dev": true, 664 | "requires": { 665 | "buffer-from": "^1.0.0", 666 | "source-map": "^0.6.0" 667 | } 668 | }, 669 | "sourcemap-codec": { 670 | "version": "1.4.8", 671 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", 672 | "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", 673 | "dev": true 674 | }, 675 | "supports-color": { 676 | "version": "5.5.0", 677 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 678 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 679 | "dev": true, 680 | "requires": { 681 | "has-flag": "^3.0.0" 682 | } 683 | }, 684 | "svelte": { 685 | "version": "3.25.1", 686 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.25.1.tgz", 687 | "integrity": "sha512-IbrVKTmuR0BvDw4ii8/gBNy8REu7nWTRy9uhUz+Yuae5lIjWgSGwKlWtJGC2Vg95s+UnXPqDu0Kk/sUwe0t2GQ==", 688 | "dev": true 689 | }, 690 | "terser": { 691 | "version": "5.3.1", 692 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.1.tgz", 693 | "integrity": "sha512-yD80f4hdwCWTH5mojzxe1q8bN1oJbsK/vfJGLcPZM/fl+/jItIVNKhFIHqqR71OipFWMLgj3Kc+GIp6CeIqfnA==", 694 | "dev": true, 695 | "requires": { 696 | "commander": "^2.20.0", 697 | "source-map": "~0.6.1", 698 | "source-map-support": "~0.5.12" 699 | } 700 | }, 701 | "tinydate": { 702 | "version": "1.3.0", 703 | "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", 704 | "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==" 705 | }, 706 | "to-regex-range": { 707 | "version": "5.0.1", 708 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 709 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 710 | "dev": true, 711 | "requires": { 712 | "is-number": "^7.0.0" 713 | } 714 | }, 715 | "totalist": { 716 | "version": "1.1.0", 717 | "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", 718 | "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" 719 | }, 720 | "wrappy": { 721 | "version": "1.0.2", 722 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 723 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 724 | "dev": true 725 | }, 726 | "ws": { 727 | "version": "6.2.1", 728 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", 729 | "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", 730 | "dev": true, 731 | "requires": { 732 | "async-limiter": "~1.0.0" 733 | } 734 | } 735 | } 736 | } 737 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "addr2line" 5 | version = "0.13.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" 8 | dependencies = [ 9 | "gimli", 10 | ] 11 | 12 | [[package]] 13 | name = "adler" 14 | version = "0.2.3" 15 | source = "registry+https://github.com/rust-lang/crates.io-index" 16 | checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" 17 | 18 | [[package]] 19 | name = "adler32" 20 | version = "1.2.0" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 23 | 24 | [[package]] 25 | name = "aho-corasick" 26 | version = "0.7.13" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" 29 | dependencies = [ 30 | "memchr", 31 | ] 32 | 33 | [[package]] 34 | name = "ansi_term" 35 | version = "0.11.0" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 38 | dependencies = [ 39 | "winapi 0.3.9", 40 | ] 41 | 42 | [[package]] 43 | name = "arc-swap" 44 | version = "0.4.7" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" 47 | 48 | [[package]] 49 | name = "arrayref" 50 | version = "0.3.6" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 53 | 54 | [[package]] 55 | name = "arrayvec" 56 | version = "0.5.1" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 59 | 60 | [[package]] 61 | name = "ascii" 62 | version = "0.8.7" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" 65 | 66 | [[package]] 67 | name = "atty" 68 | version = "0.2.14" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 71 | dependencies = [ 72 | "hermit-abi", 73 | "libc", 74 | "winapi 0.3.9", 75 | ] 76 | 77 | [[package]] 78 | name = "autocfg" 79 | version = "0.1.7" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 82 | 83 | [[package]] 84 | name = "autocfg" 85 | version = "1.0.0" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 88 | 89 | [[package]] 90 | name = "backtrace" 91 | version = "0.3.50" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" 94 | dependencies = [ 95 | "addr2line", 96 | "cfg-if", 97 | "libc", 98 | "miniz_oxide", 99 | "object", 100 | "rustc-demangle", 101 | ] 102 | 103 | [[package]] 104 | name = "base64" 105 | version = "0.9.3" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" 108 | dependencies = [ 109 | "byteorder", 110 | "safemem", 111 | ] 112 | 113 | [[package]] 114 | name = "base64" 115 | version = "0.12.3" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 118 | 119 | [[package]] 120 | name = "bindgen" 121 | version = "0.53.3" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5" 124 | dependencies = [ 125 | "bitflags", 126 | "cexpr", 127 | "cfg-if", 128 | "clang-sys", 129 | "clap", 130 | "env_logger", 131 | "lazy_static", 132 | "lazycell", 133 | "log 0.4.11", 134 | "peeking_take_while", 135 | "proc-macro2", 136 | "quote", 137 | "regex", 138 | "rustc-hash", 139 | "shlex", 140 | "which", 141 | ] 142 | 143 | [[package]] 144 | name = "bitflags" 145 | version = "1.2.1" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 148 | 149 | [[package]] 150 | name = "blake2b_simd" 151 | version = "0.5.10" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" 154 | dependencies = [ 155 | "arrayref", 156 | "arrayvec", 157 | "constant_time_eq", 158 | ] 159 | 160 | [[package]] 161 | name = "block-buffer" 162 | version = "0.9.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 165 | dependencies = [ 166 | "generic-array", 167 | ] 168 | 169 | [[package]] 170 | name = "brotli-sys" 171 | version = "0.3.2" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" 174 | dependencies = [ 175 | "cc", 176 | "libc", 177 | ] 178 | 179 | [[package]] 180 | name = "brotli2" 181 | version = "0.3.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" 184 | dependencies = [ 185 | "brotli-sys", 186 | "libc", 187 | ] 188 | 189 | [[package]] 190 | name = "bstr" 191 | version = "0.2.13" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" 194 | dependencies = [ 195 | "memchr", 196 | ] 197 | 198 | [[package]] 199 | name = "buf_redux" 200 | version = "0.8.4" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" 203 | dependencies = [ 204 | "memchr", 205 | "safemem", 206 | ] 207 | 208 | [[package]] 209 | name = "bumpalo" 210 | version = "3.4.0" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" 213 | 214 | [[package]] 215 | name = "byteorder" 216 | version = "1.3.4" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 219 | 220 | [[package]] 221 | name = "bytes" 222 | version = "0.4.12" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 225 | dependencies = [ 226 | "byteorder", 227 | "either", 228 | "iovec", 229 | ] 230 | 231 | [[package]] 232 | name = "bytes" 233 | version = "0.5.6" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" 236 | 237 | [[package]] 238 | name = "cc" 239 | version = "1.0.41" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff" 242 | dependencies = [ 243 | "rayon", 244 | ] 245 | 246 | [[package]] 247 | name = "cexpr" 248 | version = "0.4.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" 251 | dependencies = [ 252 | "nom", 253 | ] 254 | 255 | [[package]] 256 | name = "cfg-if" 257 | version = "0.1.10" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 260 | 261 | [[package]] 262 | name = "chrono" 263 | version = "0.4.15" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" 266 | dependencies = [ 267 | "num-integer", 268 | "num-traits 0.2.12", 269 | "time", 270 | ] 271 | 272 | [[package]] 273 | name = "chunked_transfer" 274 | version = "0.3.1" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" 277 | 278 | [[package]] 279 | name = "clang-sys" 280 | version = "0.29.3" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" 283 | dependencies = [ 284 | "glob", 285 | "libc", 286 | "libloading", 287 | ] 288 | 289 | [[package]] 290 | name = "clap" 291 | version = "2.33.1" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" 294 | dependencies = [ 295 | "ansi_term", 296 | "atty", 297 | "bitflags", 298 | "strsim", 299 | "textwrap", 300 | "unicode-width", 301 | "vec_map", 302 | ] 303 | 304 | [[package]] 305 | name = "cloudabi" 306 | version = "0.0.3" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 309 | dependencies = [ 310 | "bitflags", 311 | ] 312 | 313 | [[package]] 314 | name = "colored" 315 | version = "2.0.0" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" 318 | dependencies = [ 319 | "atty", 320 | "lazy_static", 321 | "winapi 0.3.9", 322 | ] 323 | 324 | [[package]] 325 | name = "config" 326 | version = "0.10.1" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" 329 | dependencies = [ 330 | "lazy_static", 331 | "nom", 332 | "rust-ini", 333 | "serde 1.0.114", 334 | "serde-hjson", 335 | "serde_json", 336 | "toml", 337 | "yaml-rust", 338 | ] 339 | 340 | [[package]] 341 | name = "constant_time_eq" 342 | version = "0.1.5" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 345 | 346 | [[package]] 347 | name = "core-foundation" 348 | version = "0.7.0" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" 351 | dependencies = [ 352 | "core-foundation-sys", 353 | "libc", 354 | ] 355 | 356 | [[package]] 357 | name = "core-foundation-sys" 358 | version = "0.7.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" 361 | 362 | [[package]] 363 | name = "cpuid-bool" 364 | version = "0.1.0" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" 367 | 368 | [[package]] 369 | name = "crc32fast" 370 | version = "1.2.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 373 | dependencies = [ 374 | "cfg-if", 375 | ] 376 | 377 | [[package]] 378 | name = "crossbeam-deque" 379 | version = "0.7.3" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 382 | dependencies = [ 383 | "crossbeam-epoch", 384 | "crossbeam-utils", 385 | "maybe-uninit", 386 | ] 387 | 388 | [[package]] 389 | name = "crossbeam-epoch" 390 | version = "0.8.2" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 393 | dependencies = [ 394 | "autocfg 1.0.0", 395 | "cfg-if", 396 | "crossbeam-utils", 397 | "lazy_static", 398 | "maybe-uninit", 399 | "memoffset", 400 | "scopeguard", 401 | ] 402 | 403 | [[package]] 404 | name = "crossbeam-queue" 405 | version = "0.2.3" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" 408 | dependencies = [ 409 | "cfg-if", 410 | "crossbeam-utils", 411 | "maybe-uninit", 412 | ] 413 | 414 | [[package]] 415 | name = "crossbeam-utils" 416 | version = "0.7.2" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 419 | dependencies = [ 420 | "autocfg 1.0.0", 421 | "cfg-if", 422 | "lazy_static", 423 | ] 424 | 425 | [[package]] 426 | name = "deflate" 427 | version = "0.7.20" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" 430 | dependencies = [ 431 | "adler32", 432 | "byteorder", 433 | "gzip-header", 434 | ] 435 | 436 | [[package]] 437 | name = "digest" 438 | version = "0.9.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 441 | dependencies = [ 442 | "generic-array", 443 | ] 444 | 445 | [[package]] 446 | name = "dirs" 447 | version = "1.0.5" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" 450 | dependencies = [ 451 | "libc", 452 | "redox_users", 453 | "winapi 0.3.9", 454 | ] 455 | 456 | [[package]] 457 | name = "dtoa" 458 | version = "0.4.6" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" 461 | 462 | [[package]] 463 | name = "either" 464 | version = "1.5.3" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 467 | 468 | [[package]] 469 | name = "encoding_rs" 470 | version = "0.8.24" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "a51b8cf747471cb9499b6d59e59b0444f4c90eba8968c4e44874e92b5b64ace2" 473 | dependencies = [ 474 | "cfg-if", 475 | ] 476 | 477 | [[package]] 478 | name = "env_logger" 479 | version = "0.7.1" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" 482 | dependencies = [ 483 | "atty", 484 | "humantime", 485 | "log 0.4.11", 486 | "regex", 487 | "termcolor", 488 | ] 489 | 490 | [[package]] 491 | name = "error-chain" 492 | version = "0.12.4" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" 495 | dependencies = [ 496 | "backtrace", 497 | "version_check 0.9.2", 498 | ] 499 | 500 | [[package]] 501 | name = "failure" 502 | version = "0.1.8" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 505 | dependencies = [ 506 | "backtrace", 507 | "failure_derive", 508 | ] 509 | 510 | [[package]] 511 | name = "failure_derive" 512 | version = "0.1.8" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 515 | dependencies = [ 516 | "proc-macro2", 517 | "quote", 518 | "syn", 519 | "synstructure", 520 | ] 521 | 522 | [[package]] 523 | name = "filetime" 524 | version = "0.2.12" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" 527 | dependencies = [ 528 | "cfg-if", 529 | "libc", 530 | "redox_syscall", 531 | "winapi 0.3.9", 532 | ] 533 | 534 | [[package]] 535 | name = "fnv" 536 | version = "1.0.7" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 539 | 540 | [[package]] 541 | name = "foreign-types" 542 | version = "0.3.2" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 545 | dependencies = [ 546 | "foreign-types-shared", 547 | ] 548 | 549 | [[package]] 550 | name = "foreign-types-shared" 551 | version = "0.1.1" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 554 | 555 | [[package]] 556 | name = "fuchsia-cprng" 557 | version = "0.1.1" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 560 | 561 | [[package]] 562 | name = "fuchsia-zircon" 563 | version = "0.3.3" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 566 | dependencies = [ 567 | "bitflags", 568 | "fuchsia-zircon-sys", 569 | ] 570 | 571 | [[package]] 572 | name = "fuchsia-zircon-sys" 573 | version = "0.3.3" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 576 | 577 | [[package]] 578 | name = "futures" 579 | version = "0.1.29" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" 582 | 583 | [[package]] 584 | name = "futures-channel" 585 | version = "0.3.5" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" 588 | dependencies = [ 589 | "futures-core", 590 | ] 591 | 592 | [[package]] 593 | name = "futures-core" 594 | version = "0.3.5" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" 597 | 598 | [[package]] 599 | name = "futures-cpupool" 600 | version = "0.1.8" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 603 | dependencies = [ 604 | "futures", 605 | "num_cpus", 606 | ] 607 | 608 | [[package]] 609 | name = "futures-sink" 610 | version = "0.3.5" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" 613 | 614 | [[package]] 615 | name = "futures-task" 616 | version = "0.3.5" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" 619 | 620 | [[package]] 621 | name = "futures-util" 622 | version = "0.3.5" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" 625 | dependencies = [ 626 | "futures-core", 627 | "futures-task", 628 | "pin-project", 629 | "pin-utils", 630 | ] 631 | 632 | [[package]] 633 | name = "generic-array" 634 | version = "0.14.2" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980" 637 | dependencies = [ 638 | "typenum", 639 | "version_check 0.9.2", 640 | ] 641 | 642 | [[package]] 643 | name = "getrandom" 644 | version = "0.1.14" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 647 | dependencies = [ 648 | "cfg-if", 649 | "libc", 650 | "wasi", 651 | ] 652 | 653 | [[package]] 654 | name = "gimli" 655 | version = "0.22.0" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" 658 | 659 | [[package]] 660 | name = "glob" 661 | version = "0.3.0" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" 664 | 665 | [[package]] 666 | name = "globset" 667 | version = "0.4.5" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" 670 | dependencies = [ 671 | "aho-corasick", 672 | "bstr", 673 | "fnv", 674 | "log 0.4.11", 675 | "regex", 676 | ] 677 | 678 | [[package]] 679 | name = "gzip-header" 680 | version = "0.3.0" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "0131feb3d3bb2a5a238d8a4d09f6353b7ebfdc52e77bccbf4ea6eaa751dde639" 683 | dependencies = [ 684 | "crc32fast", 685 | ] 686 | 687 | [[package]] 688 | name = "h2" 689 | version = "0.1.26" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 692 | dependencies = [ 693 | "byteorder", 694 | "bytes 0.4.12", 695 | "fnv", 696 | "futures", 697 | "http 0.1.21", 698 | "indexmap", 699 | "log 0.4.11", 700 | "slab 0.4.2", 701 | "string", 702 | "tokio-io", 703 | ] 704 | 705 | [[package]] 706 | name = "h2" 707 | version = "0.2.6" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" 710 | dependencies = [ 711 | "bytes 0.5.6", 712 | "fnv", 713 | "futures-core", 714 | "futures-sink", 715 | "futures-util", 716 | "http 0.2.1", 717 | "indexmap", 718 | "slab 0.4.2", 719 | "tokio 0.2.22", 720 | "tokio-util", 721 | "tracing", 722 | ] 723 | 724 | [[package]] 725 | name = "hashbrown" 726 | version = "0.8.2" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" 729 | dependencies = [ 730 | "autocfg 1.0.0", 731 | ] 732 | 733 | [[package]] 734 | name = "hermit-abi" 735 | version = "0.1.15" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" 738 | dependencies = [ 739 | "libc", 740 | ] 741 | 742 | [[package]] 743 | name = "hex" 744 | version = "0.4.2" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" 747 | 748 | [[package]] 749 | name = "http" 750 | version = "0.1.21" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 753 | dependencies = [ 754 | "bytes 0.4.12", 755 | "fnv", 756 | "itoa", 757 | ] 758 | 759 | [[package]] 760 | name = "http" 761 | version = "0.2.1" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" 764 | dependencies = [ 765 | "bytes 0.5.6", 766 | "fnv", 767 | "itoa", 768 | ] 769 | 770 | [[package]] 771 | name = "http-body" 772 | version = "0.1.0" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 775 | dependencies = [ 776 | "bytes 0.4.12", 777 | "futures", 778 | "http 0.1.21", 779 | "tokio-buf", 780 | ] 781 | 782 | [[package]] 783 | name = "http-body" 784 | version = "0.3.1" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" 787 | dependencies = [ 788 | "bytes 0.5.6", 789 | "http 0.2.1", 790 | ] 791 | 792 | [[package]] 793 | name = "httparse" 794 | version = "1.3.4" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 797 | 798 | [[package]] 799 | name = "humantime" 800 | version = "1.3.0" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 803 | dependencies = [ 804 | "quick-error", 805 | ] 806 | 807 | [[package]] 808 | name = "hyper" 809 | version = "0.11.27" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" 812 | dependencies = [ 813 | "base64 0.9.3", 814 | "bytes 0.4.12", 815 | "futures", 816 | "futures-cpupool", 817 | "httparse", 818 | "iovec", 819 | "language-tags", 820 | "log 0.4.11", 821 | "mime 0.3.16", 822 | "net2", 823 | "percent-encoding 1.0.1", 824 | "relay", 825 | "time", 826 | "tokio-core", 827 | "tokio-io", 828 | "tokio-proto", 829 | "tokio-service", 830 | "unicase 2.6.0", 831 | "want 0.0.4", 832 | ] 833 | 834 | [[package]] 835 | name = "hyper" 836 | version = "0.12.35" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" 839 | dependencies = [ 840 | "bytes 0.4.12", 841 | "futures", 842 | "futures-cpupool", 843 | "h2 0.1.26", 844 | "http 0.1.21", 845 | "http-body 0.1.0", 846 | "httparse", 847 | "iovec", 848 | "itoa", 849 | "log 0.4.11", 850 | "net2", 851 | "rustc_version", 852 | "time", 853 | "tokio 0.1.22", 854 | "tokio-buf", 855 | "tokio-executor", 856 | "tokio-io", 857 | "tokio-reactor", 858 | "tokio-tcp", 859 | "tokio-threadpool", 860 | "tokio-timer", 861 | "want 0.2.0", 862 | ] 863 | 864 | [[package]] 865 | name = "hyper" 866 | version = "0.13.7" 867 | source = "registry+https://github.com/rust-lang/crates.io-index" 868 | checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb" 869 | dependencies = [ 870 | "bytes 0.5.6", 871 | "futures-channel", 872 | "futures-core", 873 | "futures-util", 874 | "h2 0.2.6", 875 | "http 0.2.1", 876 | "http-body 0.3.1", 877 | "httparse", 878 | "itoa", 879 | "pin-project", 880 | "socket2", 881 | "time", 882 | "tokio 0.2.22", 883 | "tower-service", 884 | "tracing", 885 | "want 0.3.0", 886 | ] 887 | 888 | [[package]] 889 | name = "hyper-tls" 890 | version = "0.4.3" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" 893 | dependencies = [ 894 | "bytes 0.5.6", 895 | "hyper 0.13.7", 896 | "native-tls", 897 | "tokio 0.2.22", 898 | "tokio-tls", 899 | ] 900 | 901 | [[package]] 902 | name = "idna" 903 | version = "0.1.5" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 906 | dependencies = [ 907 | "matches", 908 | "unicode-bidi", 909 | "unicode-normalization", 910 | ] 911 | 912 | [[package]] 913 | name = "idna" 914 | version = "0.2.0" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 917 | dependencies = [ 918 | "matches", 919 | "unicode-bidi", 920 | "unicode-normalization", 921 | ] 922 | 923 | [[package]] 924 | name = "indexmap" 925 | version = "1.5.1" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9" 928 | dependencies = [ 929 | "autocfg 1.0.0", 930 | "hashbrown", 931 | ] 932 | 933 | [[package]] 934 | name = "iovec" 935 | version = "0.1.4" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 938 | dependencies = [ 939 | "libc", 940 | ] 941 | 942 | [[package]] 943 | name = "ipnet" 944 | version = "2.3.0" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" 947 | 948 | [[package]] 949 | name = "itoa" 950 | version = "0.4.6" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 953 | 954 | [[package]] 955 | name = "js-sys" 956 | version = "0.3.44" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73" 959 | dependencies = [ 960 | "wasm-bindgen", 961 | ] 962 | 963 | [[package]] 964 | name = "jsonrpc-client-core" 965 | version = "0.5.0" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e" 968 | dependencies = [ 969 | "error-chain", 970 | "futures", 971 | "jsonrpc-core 8.0.1", 972 | "log 0.4.11", 973 | "serde 1.0.114", 974 | "serde_json", 975 | ] 976 | 977 | [[package]] 978 | name = "jsonrpc-client-http" 979 | version = "0.5.0" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302" 982 | dependencies = [ 983 | "error-chain", 984 | "futures", 985 | "hyper 0.11.27", 986 | "jsonrpc-client-core", 987 | "log 0.4.11", 988 | "tokio-core", 989 | ] 990 | 991 | [[package]] 992 | name = "jsonrpc-client-transports" 993 | version = "14.2.1" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "2773fa94a2a1fd51efb89a8f45b8861023dbb415d18d3c9235ae9388d780f9ec" 996 | dependencies = [ 997 | "failure", 998 | "futures", 999 | "hyper 0.12.35", 1000 | "jsonrpc-core 14.2.0", 1001 | "jsonrpc-pubsub", 1002 | "log 0.4.11", 1003 | "serde 1.0.114", 1004 | "serde_json", 1005 | "url 1.7.2", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "jsonrpc-core" 1010 | version = "8.0.1" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" 1013 | dependencies = [ 1014 | "futures", 1015 | "log 0.3.9", 1016 | "serde 1.0.114", 1017 | "serde_derive", 1018 | "serde_json", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "jsonrpc-core" 1023 | version = "14.2.0" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "a0747307121ffb9703afd93afbd0fb4f854c38fb873f2c8b90e0e902f27c7b62" 1026 | dependencies = [ 1027 | "futures", 1028 | "log 0.4.11", 1029 | "serde 1.0.114", 1030 | "serde_derive", 1031 | "serde_json", 1032 | ] 1033 | 1034 | [[package]] 1035 | name = "jsonrpc-core-client" 1036 | version = "14.2.0" 1037 | source = "registry+https://github.com/rust-lang/crates.io-index" 1038 | checksum = "34221123bc79b66279a3fde2d3363553835b43092d629b34f2e760c44dc94713" 1039 | dependencies = [ 1040 | "jsonrpc-client-transports", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "jsonrpc-derive" 1045 | version = "14.2.1" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "0fadf6945e227246825a583514534d864554e9f23d80b3c77d034b10983db5ef" 1048 | dependencies = [ 1049 | "proc-macro-crate", 1050 | "proc-macro2", 1051 | "quote", 1052 | "syn", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "jsonrpc-http-server" 1057 | version = "14.2.0" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "0da906d682799df05754480dac1b9e70ec92e12c19ebafd2662a5ea1c9fd6522" 1060 | dependencies = [ 1061 | "hyper 0.12.35", 1062 | "jsonrpc-core 14.2.0", 1063 | "jsonrpc-server-utils", 1064 | "log 0.4.11", 1065 | "net2", 1066 | "parking_lot 0.10.2", 1067 | "unicase 2.6.0", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "jsonrpc-pubsub" 1072 | version = "14.2.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "2d44f5602a11d657946aac09357956d2841299ed422035edf140c552cb057986" 1075 | dependencies = [ 1076 | "jsonrpc-core 14.2.0", 1077 | "log 0.4.11", 1078 | "parking_lot 0.10.2", 1079 | "rand 0.7.3", 1080 | "serde 1.0.114", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "jsonrpc-server-utils" 1085 | version = "14.2.0" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "56cbfb462e7f902e21121d9f0d1c2b77b2c5b642e1a4e8f4ebfa2e15b94402bb" 1088 | dependencies = [ 1089 | "bytes 0.4.12", 1090 | "globset", 1091 | "jsonrpc-core 14.2.0", 1092 | "lazy_static", 1093 | "log 0.4.11", 1094 | "tokio 0.1.22", 1095 | "tokio-codec", 1096 | "unicase 2.6.0", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "kernel32-sys" 1101 | version = "0.2.2" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1104 | dependencies = [ 1105 | "winapi 0.2.8", 1106 | "winapi-build", 1107 | ] 1108 | 1109 | [[package]] 1110 | name = "language-tags" 1111 | version = "0.2.2" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1114 | 1115 | [[package]] 1116 | name = "lazy_static" 1117 | version = "1.4.0" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1120 | 1121 | [[package]] 1122 | name = "lazycell" 1123 | version = "1.2.1" 1124 | source = "registry+https://github.com/rust-lang/crates.io-index" 1125 | checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 1126 | 1127 | [[package]] 1128 | name = "lexical-core" 1129 | version = "0.7.4" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" 1132 | dependencies = [ 1133 | "arrayvec", 1134 | "bitflags", 1135 | "cfg-if", 1136 | "ryu", 1137 | "static_assertions", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "libc" 1142 | version = "0.2.76" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" 1145 | 1146 | [[package]] 1147 | name = "libloading" 1148 | version = "0.5.2" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 1151 | dependencies = [ 1152 | "cc", 1153 | "winapi 0.3.9", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "librocksdb-sys" 1158 | version = "6.7.4" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "883213ae3d09bfc3d104aefe94b25ebb183b6f4d3a515b23b14817e1f4854005" 1161 | dependencies = [ 1162 | "bindgen", 1163 | "cc", 1164 | "glob", 1165 | "libc", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "linked-hash-map" 1170 | version = "0.3.0" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" 1173 | dependencies = [ 1174 | "serde 0.8.23", 1175 | "serde_test", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "linked-hash-map" 1180 | version = "0.5.3" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 1183 | 1184 | [[package]] 1185 | name = "lock_api" 1186 | version = "0.3.4" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 1189 | dependencies = [ 1190 | "scopeguard", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "log" 1195 | version = "0.3.9" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" 1198 | dependencies = [ 1199 | "log 0.4.11", 1200 | ] 1201 | 1202 | [[package]] 1203 | name = "log" 1204 | version = "0.4.11" 1205 | source = "registry+https://github.com/rust-lang/crates.io-index" 1206 | checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" 1207 | dependencies = [ 1208 | "cfg-if", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "matches" 1213 | version = "0.1.8" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1216 | 1217 | [[package]] 1218 | name = "maybe-uninit" 1219 | version = "2.0.0" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 1222 | 1223 | [[package]] 1224 | name = "memchr" 1225 | version = "2.3.3" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 1228 | 1229 | [[package]] 1230 | name = "memoffset" 1231 | version = "0.5.5" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" 1234 | dependencies = [ 1235 | "autocfg 1.0.0", 1236 | ] 1237 | 1238 | [[package]] 1239 | name = "mime" 1240 | version = "0.2.6" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" 1243 | dependencies = [ 1244 | "log 0.3.9", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "mime" 1249 | version = "0.3.16" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 1252 | 1253 | [[package]] 1254 | name = "mime_guess" 1255 | version = "1.8.8" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3" 1258 | dependencies = [ 1259 | "mime 0.2.6", 1260 | "phf", 1261 | "phf_codegen", 1262 | "unicase 1.4.2", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "mime_guess" 1267 | version = "2.0.3" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" 1270 | dependencies = [ 1271 | "mime 0.3.16", 1272 | "unicase 2.6.0", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "miniz_oxide" 1277 | version = "0.4.1" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722" 1280 | dependencies = [ 1281 | "adler", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "mio" 1286 | version = "0.6.22" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 1289 | dependencies = [ 1290 | "cfg-if", 1291 | "fuchsia-zircon", 1292 | "fuchsia-zircon-sys", 1293 | "iovec", 1294 | "kernel32-sys", 1295 | "libc", 1296 | "log 0.4.11", 1297 | "miow 0.2.1", 1298 | "net2", 1299 | "slab 0.4.2", 1300 | "winapi 0.2.8", 1301 | ] 1302 | 1303 | [[package]] 1304 | name = "mio-named-pipes" 1305 | version = "0.1.7" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" 1308 | dependencies = [ 1309 | "log 0.4.11", 1310 | "mio", 1311 | "miow 0.3.5", 1312 | "winapi 0.3.9", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "mio-uds" 1317 | version = "0.6.8" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" 1320 | dependencies = [ 1321 | "iovec", 1322 | "libc", 1323 | "mio", 1324 | ] 1325 | 1326 | [[package]] 1327 | name = "miow" 1328 | version = "0.2.1" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1331 | dependencies = [ 1332 | "kernel32-sys", 1333 | "net2", 1334 | "winapi 0.2.8", 1335 | "ws2_32-sys", 1336 | ] 1337 | 1338 | [[package]] 1339 | name = "miow" 1340 | version = "0.3.5" 1341 | source = "registry+https://github.com/rust-lang/crates.io-index" 1342 | checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" 1343 | dependencies = [ 1344 | "socket2", 1345 | "winapi 0.3.9", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "multipart" 1350 | version = "0.15.4" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "adba94490a79baf2d6a23eac897157047008272fa3eecb3373ae6377b91eca28" 1353 | dependencies = [ 1354 | "buf_redux", 1355 | "httparse", 1356 | "log 0.4.11", 1357 | "mime 0.2.6", 1358 | "mime_guess 1.8.8", 1359 | "quick-error", 1360 | "rand 0.4.6", 1361 | "safemem", 1362 | "tempdir", 1363 | "twoway", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "native-tls" 1368 | version = "0.2.4" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" 1371 | dependencies = [ 1372 | "lazy_static", 1373 | "libc", 1374 | "log 0.4.11", 1375 | "openssl", 1376 | "openssl-probe", 1377 | "openssl-sys", 1378 | "schannel", 1379 | "security-framework", 1380 | "security-framework-sys", 1381 | "tempfile", 1382 | ] 1383 | 1384 | [[package]] 1385 | name = "net2" 1386 | version = "0.2.34" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" 1389 | dependencies = [ 1390 | "cfg-if", 1391 | "libc", 1392 | "winapi 0.3.9", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "nibble" 1397 | version = "0.2.0" 1398 | dependencies = [ 1399 | "clap", 1400 | "colored", 1401 | "config", 1402 | "generic-array", 1403 | "hex", 1404 | "jsonrpc-client-core", 1405 | "jsonrpc-client-http", 1406 | "jsonrpc-core 14.2.0", 1407 | "jsonrpc-core-client", 1408 | "jsonrpc-derive", 1409 | "jsonrpc-http-server", 1410 | "regex", 1411 | "reqwest", 1412 | "rocksdb", 1413 | "rouille", 1414 | "secp256k1", 1415 | "serde 1.0.114", 1416 | "serde_json", 1417 | "sha2", 1418 | "tokio 0.2.22", 1419 | "toml", 1420 | "typenum", 1421 | ] 1422 | 1423 | [[package]] 1424 | name = "nom" 1425 | version = "5.1.2" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" 1428 | dependencies = [ 1429 | "lexical-core", 1430 | "memchr", 1431 | "version_check 0.9.2", 1432 | ] 1433 | 1434 | [[package]] 1435 | name = "num-integer" 1436 | version = "0.1.43" 1437 | source = "registry+https://github.com/rust-lang/crates.io-index" 1438 | checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" 1439 | dependencies = [ 1440 | "autocfg 1.0.0", 1441 | "num-traits 0.2.12", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "num-traits" 1446 | version = "0.1.43" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" 1449 | dependencies = [ 1450 | "num-traits 0.2.12", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "num-traits" 1455 | version = "0.2.12" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" 1458 | dependencies = [ 1459 | "autocfg 1.0.0", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "num_cpus" 1464 | version = "1.13.0" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 1467 | dependencies = [ 1468 | "hermit-abi", 1469 | "libc", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "object" 1474 | version = "0.20.0" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" 1477 | 1478 | [[package]] 1479 | name = "opaque-debug" 1480 | version = "0.3.0" 1481 | source = "registry+https://github.com/rust-lang/crates.io-index" 1482 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 1483 | 1484 | [[package]] 1485 | name = "openssl" 1486 | version = "0.10.30" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" 1489 | dependencies = [ 1490 | "bitflags", 1491 | "cfg-if", 1492 | "foreign-types", 1493 | "lazy_static", 1494 | "libc", 1495 | "openssl-sys", 1496 | ] 1497 | 1498 | [[package]] 1499 | name = "openssl-probe" 1500 | version = "0.1.2" 1501 | source = "registry+https://github.com/rust-lang/crates.io-index" 1502 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1503 | 1504 | [[package]] 1505 | name = "openssl-sys" 1506 | version = "0.9.58" 1507 | source = "registry+https://github.com/rust-lang/crates.io-index" 1508 | checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" 1509 | dependencies = [ 1510 | "autocfg 1.0.0", 1511 | "cc", 1512 | "libc", 1513 | "pkg-config", 1514 | "vcpkg", 1515 | ] 1516 | 1517 | [[package]] 1518 | name = "parking_lot" 1519 | version = "0.9.0" 1520 | source = "registry+https://github.com/rust-lang/crates.io-index" 1521 | checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1522 | dependencies = [ 1523 | "lock_api", 1524 | "parking_lot_core 0.6.2", 1525 | "rustc_version", 1526 | ] 1527 | 1528 | [[package]] 1529 | name = "parking_lot" 1530 | version = "0.10.2" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" 1533 | dependencies = [ 1534 | "lock_api", 1535 | "parking_lot_core 0.7.2", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "parking_lot_core" 1540 | version = "0.6.2" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 1543 | dependencies = [ 1544 | "cfg-if", 1545 | "cloudabi", 1546 | "libc", 1547 | "redox_syscall", 1548 | "rustc_version", 1549 | "smallvec 0.6.13", 1550 | "winapi 0.3.9", 1551 | ] 1552 | 1553 | [[package]] 1554 | name = "parking_lot_core" 1555 | version = "0.7.2" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" 1558 | dependencies = [ 1559 | "cfg-if", 1560 | "cloudabi", 1561 | "libc", 1562 | "redox_syscall", 1563 | "smallvec 1.4.1", 1564 | "winapi 0.3.9", 1565 | ] 1566 | 1567 | [[package]] 1568 | name = "peeking_take_while" 1569 | version = "0.1.2" 1570 | source = "registry+https://github.com/rust-lang/crates.io-index" 1571 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 1572 | 1573 | [[package]] 1574 | name = "percent-encoding" 1575 | version = "1.0.1" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1578 | 1579 | [[package]] 1580 | name = "percent-encoding" 1581 | version = "2.1.0" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1584 | 1585 | [[package]] 1586 | name = "phf" 1587 | version = "0.7.24" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" 1590 | dependencies = [ 1591 | "phf_shared", 1592 | ] 1593 | 1594 | [[package]] 1595 | name = "phf_codegen" 1596 | version = "0.7.24" 1597 | source = "registry+https://github.com/rust-lang/crates.io-index" 1598 | checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" 1599 | dependencies = [ 1600 | "phf_generator", 1601 | "phf_shared", 1602 | ] 1603 | 1604 | [[package]] 1605 | name = "phf_generator" 1606 | version = "0.7.24" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" 1609 | dependencies = [ 1610 | "phf_shared", 1611 | "rand 0.6.5", 1612 | ] 1613 | 1614 | [[package]] 1615 | name = "phf_shared" 1616 | version = "0.7.24" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" 1619 | dependencies = [ 1620 | "siphasher", 1621 | "unicase 1.4.2", 1622 | ] 1623 | 1624 | [[package]] 1625 | name = "pin-project" 1626 | version = "0.4.23" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa" 1629 | dependencies = [ 1630 | "pin-project-internal", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "pin-project-internal" 1635 | version = "0.4.23" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f" 1638 | dependencies = [ 1639 | "proc-macro2", 1640 | "quote", 1641 | "syn", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "pin-project-lite" 1646 | version = "0.1.7" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" 1649 | 1650 | [[package]] 1651 | name = "pin-utils" 1652 | version = "0.1.0" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1655 | 1656 | [[package]] 1657 | name = "pkg-config" 1658 | version = "0.3.18" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" 1661 | 1662 | [[package]] 1663 | name = "ppv-lite86" 1664 | version = "0.2.9" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" 1667 | 1668 | [[package]] 1669 | name = "proc-macro-crate" 1670 | version = "0.1.5" 1671 | source = "registry+https://github.com/rust-lang/crates.io-index" 1672 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1673 | dependencies = [ 1674 | "toml", 1675 | ] 1676 | 1677 | [[package]] 1678 | name = "proc-macro2" 1679 | version = "1.0.19" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" 1682 | dependencies = [ 1683 | "unicode-xid", 1684 | ] 1685 | 1686 | [[package]] 1687 | name = "quick-error" 1688 | version = "1.2.3" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1691 | 1692 | [[package]] 1693 | name = "quote" 1694 | version = "1.0.7" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 1697 | dependencies = [ 1698 | "proc-macro2", 1699 | ] 1700 | 1701 | [[package]] 1702 | name = "rand" 1703 | version = "0.3.23" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 1706 | dependencies = [ 1707 | "libc", 1708 | "rand 0.4.6", 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "rand" 1713 | version = "0.4.6" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 1716 | dependencies = [ 1717 | "fuchsia-cprng", 1718 | "libc", 1719 | "rand_core 0.3.1", 1720 | "rdrand", 1721 | "winapi 0.3.9", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "rand" 1726 | version = "0.5.6" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" 1729 | dependencies = [ 1730 | "cloudabi", 1731 | "fuchsia-cprng", 1732 | "libc", 1733 | "rand_core 0.3.1", 1734 | "winapi 0.3.9", 1735 | ] 1736 | 1737 | [[package]] 1738 | name = "rand" 1739 | version = "0.6.5" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1742 | dependencies = [ 1743 | "autocfg 0.1.7", 1744 | "libc", 1745 | "rand_chacha 0.1.1", 1746 | "rand_core 0.4.2", 1747 | "rand_hc 0.1.0", 1748 | "rand_isaac", 1749 | "rand_jitter", 1750 | "rand_os", 1751 | "rand_pcg", 1752 | "rand_xorshift", 1753 | "winapi 0.3.9", 1754 | ] 1755 | 1756 | [[package]] 1757 | name = "rand" 1758 | version = "0.7.3" 1759 | source = "registry+https://github.com/rust-lang/crates.io-index" 1760 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1761 | dependencies = [ 1762 | "getrandom", 1763 | "libc", 1764 | "rand_chacha 0.2.2", 1765 | "rand_core 0.5.1", 1766 | "rand_hc 0.2.0", 1767 | ] 1768 | 1769 | [[package]] 1770 | name = "rand_chacha" 1771 | version = "0.1.1" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1774 | dependencies = [ 1775 | "autocfg 0.1.7", 1776 | "rand_core 0.3.1", 1777 | ] 1778 | 1779 | [[package]] 1780 | name = "rand_chacha" 1781 | version = "0.2.2" 1782 | source = "registry+https://github.com/rust-lang/crates.io-index" 1783 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1784 | dependencies = [ 1785 | "ppv-lite86", 1786 | "rand_core 0.5.1", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "rand_core" 1791 | version = "0.3.1" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1794 | dependencies = [ 1795 | "rand_core 0.4.2", 1796 | ] 1797 | 1798 | [[package]] 1799 | name = "rand_core" 1800 | version = "0.4.2" 1801 | source = "registry+https://github.com/rust-lang/crates.io-index" 1802 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1803 | 1804 | [[package]] 1805 | name = "rand_core" 1806 | version = "0.5.1" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1809 | dependencies = [ 1810 | "getrandom", 1811 | ] 1812 | 1813 | [[package]] 1814 | name = "rand_hc" 1815 | version = "0.1.0" 1816 | source = "registry+https://github.com/rust-lang/crates.io-index" 1817 | checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1818 | dependencies = [ 1819 | "rand_core 0.3.1", 1820 | ] 1821 | 1822 | [[package]] 1823 | name = "rand_hc" 1824 | version = "0.2.0" 1825 | source = "registry+https://github.com/rust-lang/crates.io-index" 1826 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1827 | dependencies = [ 1828 | "rand_core 0.5.1", 1829 | ] 1830 | 1831 | [[package]] 1832 | name = "rand_isaac" 1833 | version = "0.1.1" 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" 1835 | checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1836 | dependencies = [ 1837 | "rand_core 0.3.1", 1838 | ] 1839 | 1840 | [[package]] 1841 | name = "rand_jitter" 1842 | version = "0.1.4" 1843 | source = "registry+https://github.com/rust-lang/crates.io-index" 1844 | checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1845 | dependencies = [ 1846 | "libc", 1847 | "rand_core 0.4.2", 1848 | "winapi 0.3.9", 1849 | ] 1850 | 1851 | [[package]] 1852 | name = "rand_os" 1853 | version = "0.1.3" 1854 | source = "registry+https://github.com/rust-lang/crates.io-index" 1855 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1856 | dependencies = [ 1857 | "cloudabi", 1858 | "fuchsia-cprng", 1859 | "libc", 1860 | "rand_core 0.4.2", 1861 | "rdrand", 1862 | "winapi 0.3.9", 1863 | ] 1864 | 1865 | [[package]] 1866 | name = "rand_pcg" 1867 | version = "0.1.2" 1868 | source = "registry+https://github.com/rust-lang/crates.io-index" 1869 | checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1870 | dependencies = [ 1871 | "autocfg 0.1.7", 1872 | "rand_core 0.4.2", 1873 | ] 1874 | 1875 | [[package]] 1876 | name = "rand_xorshift" 1877 | version = "0.1.1" 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" 1879 | checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1880 | dependencies = [ 1881 | "rand_core 0.3.1", 1882 | ] 1883 | 1884 | [[package]] 1885 | name = "rayon" 1886 | version = "1.3.1" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" 1889 | dependencies = [ 1890 | "autocfg 1.0.0", 1891 | "crossbeam-deque", 1892 | "either", 1893 | "rayon-core", 1894 | ] 1895 | 1896 | [[package]] 1897 | name = "rayon-core" 1898 | version = "1.7.1" 1899 | source = "registry+https://github.com/rust-lang/crates.io-index" 1900 | checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" 1901 | dependencies = [ 1902 | "crossbeam-deque", 1903 | "crossbeam-queue", 1904 | "crossbeam-utils", 1905 | "lazy_static", 1906 | "num_cpus", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "rdrand" 1911 | version = "0.4.0" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1914 | dependencies = [ 1915 | "rand_core 0.3.1", 1916 | ] 1917 | 1918 | [[package]] 1919 | name = "redox_syscall" 1920 | version = "0.1.57" 1921 | source = "registry+https://github.com/rust-lang/crates.io-index" 1922 | checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 1923 | 1924 | [[package]] 1925 | name = "redox_users" 1926 | version = "0.3.5" 1927 | source = "registry+https://github.com/rust-lang/crates.io-index" 1928 | checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" 1929 | dependencies = [ 1930 | "getrandom", 1931 | "redox_syscall", 1932 | "rust-argon2", 1933 | ] 1934 | 1935 | [[package]] 1936 | name = "regex" 1937 | version = "1.3.9" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" 1940 | dependencies = [ 1941 | "aho-corasick", 1942 | "memchr", 1943 | "regex-syntax", 1944 | "thread_local", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "regex-syntax" 1949 | version = "0.6.18" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" 1952 | 1953 | [[package]] 1954 | name = "relay" 1955 | version = "0.1.1" 1956 | source = "registry+https://github.com/rust-lang/crates.io-index" 1957 | checksum = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" 1958 | dependencies = [ 1959 | "futures", 1960 | ] 1961 | 1962 | [[package]] 1963 | name = "remove_dir_all" 1964 | version = "0.5.3" 1965 | source = "registry+https://github.com/rust-lang/crates.io-index" 1966 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1967 | dependencies = [ 1968 | "winapi 0.3.9", 1969 | ] 1970 | 1971 | [[package]] 1972 | name = "reqwest" 1973 | version = "0.10.7" 1974 | source = "registry+https://github.com/rust-lang/crates.io-index" 1975 | checksum = "12427a5577082c24419c9c417db35cfeb65962efc7675bb6b0d5f1f9d315bfe6" 1976 | dependencies = [ 1977 | "base64 0.12.3", 1978 | "bytes 0.5.6", 1979 | "encoding_rs", 1980 | "futures-core", 1981 | "futures-util", 1982 | "http 0.2.1", 1983 | "http-body 0.3.1", 1984 | "hyper 0.13.7", 1985 | "hyper-tls", 1986 | "ipnet", 1987 | "js-sys", 1988 | "lazy_static", 1989 | "log 0.4.11", 1990 | "mime 0.3.16", 1991 | "mime_guess 2.0.3", 1992 | "native-tls", 1993 | "percent-encoding 2.1.0", 1994 | "pin-project-lite", 1995 | "serde 1.0.114", 1996 | "serde_json", 1997 | "serde_urlencoded", 1998 | "tokio 0.2.22", 1999 | "tokio-tls", 2000 | "url 2.1.1", 2001 | "wasm-bindgen", 2002 | "wasm-bindgen-futures", 2003 | "web-sys", 2004 | "winreg", 2005 | ] 2006 | 2007 | [[package]] 2008 | name = "rocksdb" 2009 | version = "0.14.0" 2010 | source = "registry+https://github.com/rust-lang/crates.io-index" 2011 | checksum = "61aa17a99a2413cd71c1106691bf59dad7de0cd5099127f90e9d99c429c40d4a" 2012 | dependencies = [ 2013 | "libc", 2014 | "librocksdb-sys", 2015 | ] 2016 | 2017 | [[package]] 2018 | name = "rouille" 2019 | version = "3.0.0" 2020 | source = "registry+https://github.com/rust-lang/crates.io-index" 2021 | checksum = "112568052ec17fa26c6c11c40acbb30d3ad244bf3d6da0be181f5e7e42e5004f" 2022 | dependencies = [ 2023 | "base64 0.9.3", 2024 | "brotli2", 2025 | "chrono", 2026 | "deflate", 2027 | "filetime", 2028 | "multipart", 2029 | "num_cpus", 2030 | "rand 0.5.6", 2031 | "serde 1.0.114", 2032 | "serde_derive", 2033 | "serde_json", 2034 | "sha1", 2035 | "term", 2036 | "threadpool", 2037 | "time", 2038 | "tiny_http", 2039 | "url 1.7.2", 2040 | ] 2041 | 2042 | [[package]] 2043 | name = "rust-argon2" 2044 | version = "0.8.2" 2045 | source = "registry+https://github.com/rust-lang/crates.io-index" 2046 | checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" 2047 | dependencies = [ 2048 | "base64 0.12.3", 2049 | "blake2b_simd", 2050 | "constant_time_eq", 2051 | "crossbeam-utils", 2052 | ] 2053 | 2054 | [[package]] 2055 | name = "rust-ini" 2056 | version = "0.13.0" 2057 | source = "registry+https://github.com/rust-lang/crates.io-index" 2058 | checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" 2059 | 2060 | [[package]] 2061 | name = "rustc-demangle" 2062 | version = "0.1.16" 2063 | source = "registry+https://github.com/rust-lang/crates.io-index" 2064 | checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 2065 | 2066 | [[package]] 2067 | name = "rustc-hash" 2068 | version = "1.1.0" 2069 | source = "registry+https://github.com/rust-lang/crates.io-index" 2070 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2071 | 2072 | [[package]] 2073 | name = "rustc_version" 2074 | version = "0.2.3" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 2077 | dependencies = [ 2078 | "semver", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "ryu" 2083 | version = "1.0.5" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 2086 | 2087 | [[package]] 2088 | name = "safemem" 2089 | version = "0.3.3" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" 2092 | 2093 | [[package]] 2094 | name = "schannel" 2095 | version = "0.1.19" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 2098 | dependencies = [ 2099 | "lazy_static", 2100 | "winapi 0.3.9", 2101 | ] 2102 | 2103 | [[package]] 2104 | name = "scoped-tls" 2105 | version = "0.1.2" 2106 | source = "registry+https://github.com/rust-lang/crates.io-index" 2107 | checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" 2108 | 2109 | [[package]] 2110 | name = "scopeguard" 2111 | version = "1.1.0" 2112 | source = "registry+https://github.com/rust-lang/crates.io-index" 2113 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 2114 | 2115 | [[package]] 2116 | name = "secp256k1" 2117 | version = "0.17.2" 2118 | source = "registry+https://github.com/rust-lang/crates.io-index" 2119 | checksum = "2932dc07acd2066ff2e3921a4419606b220ba6cd03a9935123856cc534877056" 2120 | dependencies = [ 2121 | "rand 0.6.5", 2122 | "secp256k1-sys", 2123 | "serde 1.0.114", 2124 | ] 2125 | 2126 | [[package]] 2127 | name = "secp256k1-sys" 2128 | version = "0.1.2" 2129 | source = "registry+https://github.com/rust-lang/crates.io-index" 2130 | checksum = "7ab2c26f0d3552a0f12e639ae8a64afc2e3db9c52fe32f5fc6c289d38519f220" 2131 | dependencies = [ 2132 | "cc", 2133 | ] 2134 | 2135 | [[package]] 2136 | name = "security-framework" 2137 | version = "0.4.4" 2138 | source = "registry+https://github.com/rust-lang/crates.io-index" 2139 | checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" 2140 | dependencies = [ 2141 | "bitflags", 2142 | "core-foundation", 2143 | "core-foundation-sys", 2144 | "libc", 2145 | "security-framework-sys", 2146 | ] 2147 | 2148 | [[package]] 2149 | name = "security-framework-sys" 2150 | version = "0.4.3" 2151 | source = "registry+https://github.com/rust-lang/crates.io-index" 2152 | checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" 2153 | dependencies = [ 2154 | "core-foundation-sys", 2155 | "libc", 2156 | ] 2157 | 2158 | [[package]] 2159 | name = "semver" 2160 | version = "0.9.0" 2161 | source = "registry+https://github.com/rust-lang/crates.io-index" 2162 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 2163 | dependencies = [ 2164 | "semver-parser", 2165 | ] 2166 | 2167 | [[package]] 2168 | name = "semver-parser" 2169 | version = "0.7.0" 2170 | source = "registry+https://github.com/rust-lang/crates.io-index" 2171 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 2172 | 2173 | [[package]] 2174 | name = "serde" 2175 | version = "0.8.23" 2176 | source = "registry+https://github.com/rust-lang/crates.io-index" 2177 | checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" 2178 | 2179 | [[package]] 2180 | name = "serde" 2181 | version = "1.0.114" 2182 | source = "registry+https://github.com/rust-lang/crates.io-index" 2183 | checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" 2184 | dependencies = [ 2185 | "serde_derive", 2186 | ] 2187 | 2188 | [[package]] 2189 | name = "serde-hjson" 2190 | version = "0.9.1" 2191 | source = "registry+https://github.com/rust-lang/crates.io-index" 2192 | checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" 2193 | dependencies = [ 2194 | "lazy_static", 2195 | "linked-hash-map 0.3.0", 2196 | "num-traits 0.1.43", 2197 | "regex", 2198 | "serde 0.8.23", 2199 | ] 2200 | 2201 | [[package]] 2202 | name = "serde_derive" 2203 | version = "1.0.114" 2204 | source = "registry+https://github.com/rust-lang/crates.io-index" 2205 | checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" 2206 | dependencies = [ 2207 | "proc-macro2", 2208 | "quote", 2209 | "syn", 2210 | ] 2211 | 2212 | [[package]] 2213 | name = "serde_json" 2214 | version = "1.0.57" 2215 | source = "registry+https://github.com/rust-lang/crates.io-index" 2216 | checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" 2217 | dependencies = [ 2218 | "itoa", 2219 | "ryu", 2220 | "serde 1.0.114", 2221 | ] 2222 | 2223 | [[package]] 2224 | name = "serde_test" 2225 | version = "0.8.23" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" 2228 | dependencies = [ 2229 | "serde 0.8.23", 2230 | ] 2231 | 2232 | [[package]] 2233 | name = "serde_urlencoded" 2234 | version = "0.6.1" 2235 | source = "registry+https://github.com/rust-lang/crates.io-index" 2236 | checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" 2237 | dependencies = [ 2238 | "dtoa", 2239 | "itoa", 2240 | "serde 1.0.114", 2241 | "url 2.1.1", 2242 | ] 2243 | 2244 | [[package]] 2245 | name = "sha1" 2246 | version = "0.6.0" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 2249 | 2250 | [[package]] 2251 | name = "sha2" 2252 | version = "0.9.1" 2253 | source = "registry+https://github.com/rust-lang/crates.io-index" 2254 | checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" 2255 | dependencies = [ 2256 | "block-buffer", 2257 | "cfg-if", 2258 | "cpuid-bool", 2259 | "digest", 2260 | "opaque-debug", 2261 | ] 2262 | 2263 | [[package]] 2264 | name = "shlex" 2265 | version = "0.1.1" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" 2268 | 2269 | [[package]] 2270 | name = "signal-hook-registry" 2271 | version = "1.2.1" 2272 | source = "registry+https://github.com/rust-lang/crates.io-index" 2273 | checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" 2274 | dependencies = [ 2275 | "arc-swap", 2276 | "libc", 2277 | ] 2278 | 2279 | [[package]] 2280 | name = "siphasher" 2281 | version = "0.2.3" 2282 | source = "registry+https://github.com/rust-lang/crates.io-index" 2283 | checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" 2284 | 2285 | [[package]] 2286 | name = "slab" 2287 | version = "0.3.0" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" 2290 | 2291 | [[package]] 2292 | name = "slab" 2293 | version = "0.4.2" 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" 2295 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 2296 | 2297 | [[package]] 2298 | name = "smallvec" 2299 | version = "0.2.1" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" 2302 | 2303 | [[package]] 2304 | name = "smallvec" 2305 | version = "0.6.13" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" 2308 | dependencies = [ 2309 | "maybe-uninit", 2310 | ] 2311 | 2312 | [[package]] 2313 | name = "smallvec" 2314 | version = "1.4.1" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" 2317 | 2318 | [[package]] 2319 | name = "socket2" 2320 | version = "0.3.12" 2321 | source = "registry+https://github.com/rust-lang/crates.io-index" 2322 | checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" 2323 | dependencies = [ 2324 | "cfg-if", 2325 | "libc", 2326 | "redox_syscall", 2327 | "winapi 0.3.9", 2328 | ] 2329 | 2330 | [[package]] 2331 | name = "static_assertions" 2332 | version = "1.1.0" 2333 | source = "registry+https://github.com/rust-lang/crates.io-index" 2334 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2335 | 2336 | [[package]] 2337 | name = "string" 2338 | version = "0.2.1" 2339 | source = "registry+https://github.com/rust-lang/crates.io-index" 2340 | checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" 2341 | dependencies = [ 2342 | "bytes 0.4.12", 2343 | ] 2344 | 2345 | [[package]] 2346 | name = "strsim" 2347 | version = "0.8.0" 2348 | source = "registry+https://github.com/rust-lang/crates.io-index" 2349 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 2350 | 2351 | [[package]] 2352 | name = "syn" 2353 | version = "1.0.36" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250" 2356 | dependencies = [ 2357 | "proc-macro2", 2358 | "quote", 2359 | "unicode-xid", 2360 | ] 2361 | 2362 | [[package]] 2363 | name = "synstructure" 2364 | version = "0.12.4" 2365 | source = "registry+https://github.com/rust-lang/crates.io-index" 2366 | checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" 2367 | dependencies = [ 2368 | "proc-macro2", 2369 | "quote", 2370 | "syn", 2371 | "unicode-xid", 2372 | ] 2373 | 2374 | [[package]] 2375 | name = "take" 2376 | version = "0.1.0" 2377 | source = "registry+https://github.com/rust-lang/crates.io-index" 2378 | checksum = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" 2379 | 2380 | [[package]] 2381 | name = "tempdir" 2382 | version = "0.3.7" 2383 | source = "registry+https://github.com/rust-lang/crates.io-index" 2384 | checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 2385 | dependencies = [ 2386 | "rand 0.4.6", 2387 | "remove_dir_all", 2388 | ] 2389 | 2390 | [[package]] 2391 | name = "tempfile" 2392 | version = "3.1.0" 2393 | source = "registry+https://github.com/rust-lang/crates.io-index" 2394 | checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 2395 | dependencies = [ 2396 | "cfg-if", 2397 | "libc", 2398 | "rand 0.7.3", 2399 | "redox_syscall", 2400 | "remove_dir_all", 2401 | "winapi 0.3.9", 2402 | ] 2403 | 2404 | [[package]] 2405 | name = "term" 2406 | version = "0.5.2" 2407 | source = "registry+https://github.com/rust-lang/crates.io-index" 2408 | checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" 2409 | dependencies = [ 2410 | "byteorder", 2411 | "dirs", 2412 | "winapi 0.3.9", 2413 | ] 2414 | 2415 | [[package]] 2416 | name = "termcolor" 2417 | version = "1.1.0" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" 2420 | dependencies = [ 2421 | "winapi-util", 2422 | ] 2423 | 2424 | [[package]] 2425 | name = "textwrap" 2426 | version = "0.11.0" 2427 | source = "registry+https://github.com/rust-lang/crates.io-index" 2428 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 2429 | dependencies = [ 2430 | "unicode-width", 2431 | ] 2432 | 2433 | [[package]] 2434 | name = "thread_local" 2435 | version = "1.0.1" 2436 | source = "registry+https://github.com/rust-lang/crates.io-index" 2437 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 2438 | dependencies = [ 2439 | "lazy_static", 2440 | ] 2441 | 2442 | [[package]] 2443 | name = "threadpool" 2444 | version = "1.8.1" 2445 | source = "registry+https://github.com/rust-lang/crates.io-index" 2446 | checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 2447 | dependencies = [ 2448 | "num_cpus", 2449 | ] 2450 | 2451 | [[package]] 2452 | name = "time" 2453 | version = "0.1.43" 2454 | source = "registry+https://github.com/rust-lang/crates.io-index" 2455 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 2456 | dependencies = [ 2457 | "libc", 2458 | "winapi 0.3.9", 2459 | ] 2460 | 2461 | [[package]] 2462 | name = "tiny_http" 2463 | version = "0.6.2" 2464 | source = "registry+https://github.com/rust-lang/crates.io-index" 2465 | checksum = "1661fa0a44c95d01604bd05c66732a446c657efb62b5164a7a083a3b552b4951" 2466 | dependencies = [ 2467 | "ascii", 2468 | "chrono", 2469 | "chunked_transfer", 2470 | "log 0.4.11", 2471 | "url 1.7.2", 2472 | ] 2473 | 2474 | [[package]] 2475 | name = "tinyvec" 2476 | version = "0.3.4" 2477 | source = "registry+https://github.com/rust-lang/crates.io-index" 2478 | checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" 2479 | 2480 | [[package]] 2481 | name = "tokio" 2482 | version = "0.1.22" 2483 | source = "registry+https://github.com/rust-lang/crates.io-index" 2484 | checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 2485 | dependencies = [ 2486 | "bytes 0.4.12", 2487 | "futures", 2488 | "mio", 2489 | "num_cpus", 2490 | "tokio-codec", 2491 | "tokio-current-thread", 2492 | "tokio-executor", 2493 | "tokio-fs", 2494 | "tokio-io", 2495 | "tokio-reactor", 2496 | "tokio-sync", 2497 | "tokio-tcp", 2498 | "tokio-threadpool", 2499 | "tokio-timer", 2500 | "tokio-udp", 2501 | "tokio-uds", 2502 | ] 2503 | 2504 | [[package]] 2505 | name = "tokio" 2506 | version = "0.2.22" 2507 | source = "registry+https://github.com/rust-lang/crates.io-index" 2508 | checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" 2509 | dependencies = [ 2510 | "bytes 0.5.6", 2511 | "fnv", 2512 | "futures-core", 2513 | "iovec", 2514 | "lazy_static", 2515 | "libc", 2516 | "memchr", 2517 | "mio", 2518 | "mio-named-pipes", 2519 | "mio-uds", 2520 | "num_cpus", 2521 | "pin-project-lite", 2522 | "signal-hook-registry", 2523 | "slab 0.4.2", 2524 | "tokio-macros", 2525 | "winapi 0.3.9", 2526 | ] 2527 | 2528 | [[package]] 2529 | name = "tokio-buf" 2530 | version = "0.1.1" 2531 | source = "registry+https://github.com/rust-lang/crates.io-index" 2532 | checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 2533 | dependencies = [ 2534 | "bytes 0.4.12", 2535 | "either", 2536 | "futures", 2537 | ] 2538 | 2539 | [[package]] 2540 | name = "tokio-codec" 2541 | version = "0.1.2" 2542 | source = "registry+https://github.com/rust-lang/crates.io-index" 2543 | checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" 2544 | dependencies = [ 2545 | "bytes 0.4.12", 2546 | "futures", 2547 | "tokio-io", 2548 | ] 2549 | 2550 | [[package]] 2551 | name = "tokio-core" 2552 | version = "0.1.17" 2553 | source = "registry+https://github.com/rust-lang/crates.io-index" 2554 | checksum = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" 2555 | dependencies = [ 2556 | "bytes 0.4.12", 2557 | "futures", 2558 | "iovec", 2559 | "log 0.4.11", 2560 | "mio", 2561 | "scoped-tls", 2562 | "tokio 0.1.22", 2563 | "tokio-executor", 2564 | "tokio-io", 2565 | "tokio-reactor", 2566 | "tokio-timer", 2567 | ] 2568 | 2569 | [[package]] 2570 | name = "tokio-current-thread" 2571 | version = "0.1.7" 2572 | source = "registry+https://github.com/rust-lang/crates.io-index" 2573 | checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" 2574 | dependencies = [ 2575 | "futures", 2576 | "tokio-executor", 2577 | ] 2578 | 2579 | [[package]] 2580 | name = "tokio-executor" 2581 | version = "0.1.10" 2582 | source = "registry+https://github.com/rust-lang/crates.io-index" 2583 | checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" 2584 | dependencies = [ 2585 | "crossbeam-utils", 2586 | "futures", 2587 | ] 2588 | 2589 | [[package]] 2590 | name = "tokio-fs" 2591 | version = "0.1.7" 2592 | source = "registry+https://github.com/rust-lang/crates.io-index" 2593 | checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" 2594 | dependencies = [ 2595 | "futures", 2596 | "tokio-io", 2597 | "tokio-threadpool", 2598 | ] 2599 | 2600 | [[package]] 2601 | name = "tokio-io" 2602 | version = "0.1.13" 2603 | source = "registry+https://github.com/rust-lang/crates.io-index" 2604 | checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" 2605 | dependencies = [ 2606 | "bytes 0.4.12", 2607 | "futures", 2608 | "log 0.4.11", 2609 | ] 2610 | 2611 | [[package]] 2612 | name = "tokio-macros" 2613 | version = "0.2.5" 2614 | source = "registry+https://github.com/rust-lang/crates.io-index" 2615 | checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" 2616 | dependencies = [ 2617 | "proc-macro2", 2618 | "quote", 2619 | "syn", 2620 | ] 2621 | 2622 | [[package]] 2623 | name = "tokio-proto" 2624 | version = "0.1.1" 2625 | source = "registry+https://github.com/rust-lang/crates.io-index" 2626 | checksum = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" 2627 | dependencies = [ 2628 | "futures", 2629 | "log 0.3.9", 2630 | "net2", 2631 | "rand 0.3.23", 2632 | "slab 0.3.0", 2633 | "smallvec 0.2.1", 2634 | "take", 2635 | "tokio-core", 2636 | "tokio-io", 2637 | "tokio-service", 2638 | ] 2639 | 2640 | [[package]] 2641 | name = "tokio-reactor" 2642 | version = "0.1.12" 2643 | source = "registry+https://github.com/rust-lang/crates.io-index" 2644 | checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" 2645 | dependencies = [ 2646 | "crossbeam-utils", 2647 | "futures", 2648 | "lazy_static", 2649 | "log 0.4.11", 2650 | "mio", 2651 | "num_cpus", 2652 | "parking_lot 0.9.0", 2653 | "slab 0.4.2", 2654 | "tokio-executor", 2655 | "tokio-io", 2656 | "tokio-sync", 2657 | ] 2658 | 2659 | [[package]] 2660 | name = "tokio-service" 2661 | version = "0.1.0" 2662 | source = "registry+https://github.com/rust-lang/crates.io-index" 2663 | checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" 2664 | dependencies = [ 2665 | "futures", 2666 | ] 2667 | 2668 | [[package]] 2669 | name = "tokio-sync" 2670 | version = "0.1.8" 2671 | source = "registry+https://github.com/rust-lang/crates.io-index" 2672 | checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" 2673 | dependencies = [ 2674 | "fnv", 2675 | "futures", 2676 | ] 2677 | 2678 | [[package]] 2679 | name = "tokio-tcp" 2680 | version = "0.1.4" 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" 2682 | checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" 2683 | dependencies = [ 2684 | "bytes 0.4.12", 2685 | "futures", 2686 | "iovec", 2687 | "mio", 2688 | "tokio-io", 2689 | "tokio-reactor", 2690 | ] 2691 | 2692 | [[package]] 2693 | name = "tokio-threadpool" 2694 | version = "0.1.18" 2695 | source = "registry+https://github.com/rust-lang/crates.io-index" 2696 | checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" 2697 | dependencies = [ 2698 | "crossbeam-deque", 2699 | "crossbeam-queue", 2700 | "crossbeam-utils", 2701 | "futures", 2702 | "lazy_static", 2703 | "log 0.4.11", 2704 | "num_cpus", 2705 | "slab 0.4.2", 2706 | "tokio-executor", 2707 | ] 2708 | 2709 | [[package]] 2710 | name = "tokio-timer" 2711 | version = "0.2.13" 2712 | source = "registry+https://github.com/rust-lang/crates.io-index" 2713 | checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" 2714 | dependencies = [ 2715 | "crossbeam-utils", 2716 | "futures", 2717 | "slab 0.4.2", 2718 | "tokio-executor", 2719 | ] 2720 | 2721 | [[package]] 2722 | name = "tokio-tls" 2723 | version = "0.3.1" 2724 | source = "registry+https://github.com/rust-lang/crates.io-index" 2725 | checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" 2726 | dependencies = [ 2727 | "native-tls", 2728 | "tokio 0.2.22", 2729 | ] 2730 | 2731 | [[package]] 2732 | name = "tokio-udp" 2733 | version = "0.1.6" 2734 | source = "registry+https://github.com/rust-lang/crates.io-index" 2735 | checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" 2736 | dependencies = [ 2737 | "bytes 0.4.12", 2738 | "futures", 2739 | "log 0.4.11", 2740 | "mio", 2741 | "tokio-codec", 2742 | "tokio-io", 2743 | "tokio-reactor", 2744 | ] 2745 | 2746 | [[package]] 2747 | name = "tokio-uds" 2748 | version = "0.2.7" 2749 | source = "registry+https://github.com/rust-lang/crates.io-index" 2750 | checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" 2751 | dependencies = [ 2752 | "bytes 0.4.12", 2753 | "futures", 2754 | "iovec", 2755 | "libc", 2756 | "log 0.4.11", 2757 | "mio", 2758 | "mio-uds", 2759 | "tokio-codec", 2760 | "tokio-io", 2761 | "tokio-reactor", 2762 | ] 2763 | 2764 | [[package]] 2765 | name = "tokio-util" 2766 | version = "0.3.1" 2767 | source = "registry+https://github.com/rust-lang/crates.io-index" 2768 | checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" 2769 | dependencies = [ 2770 | "bytes 0.5.6", 2771 | "futures-core", 2772 | "futures-sink", 2773 | "log 0.4.11", 2774 | "pin-project-lite", 2775 | "tokio 0.2.22", 2776 | ] 2777 | 2778 | [[package]] 2779 | name = "toml" 2780 | version = "0.5.6" 2781 | source = "registry+https://github.com/rust-lang/crates.io-index" 2782 | checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" 2783 | dependencies = [ 2784 | "serde 1.0.114", 2785 | ] 2786 | 2787 | [[package]] 2788 | name = "tower-service" 2789 | version = "0.3.0" 2790 | source = "registry+https://github.com/rust-lang/crates.io-index" 2791 | checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" 2792 | 2793 | [[package]] 2794 | name = "tracing" 2795 | version = "0.1.19" 2796 | source = "registry+https://github.com/rust-lang/crates.io-index" 2797 | checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c" 2798 | dependencies = [ 2799 | "cfg-if", 2800 | "log 0.4.11", 2801 | "tracing-core", 2802 | ] 2803 | 2804 | [[package]] 2805 | name = "tracing-core" 2806 | version = "0.1.15" 2807 | source = "registry+https://github.com/rust-lang/crates.io-index" 2808 | checksum = "4f0e00789804e99b20f12bc7003ca416309d28a6f495d6af58d1e2c2842461b5" 2809 | dependencies = [ 2810 | "lazy_static", 2811 | ] 2812 | 2813 | [[package]] 2814 | name = "try-lock" 2815 | version = "0.1.0" 2816 | source = "registry+https://github.com/rust-lang/crates.io-index" 2817 | checksum = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" 2818 | 2819 | [[package]] 2820 | name = "try-lock" 2821 | version = "0.2.3" 2822 | source = "registry+https://github.com/rust-lang/crates.io-index" 2823 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 2824 | 2825 | [[package]] 2826 | name = "twoway" 2827 | version = "0.1.8" 2828 | source = "registry+https://github.com/rust-lang/crates.io-index" 2829 | checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" 2830 | dependencies = [ 2831 | "memchr", 2832 | ] 2833 | 2834 | [[package]] 2835 | name = "typenum" 2836 | version = "1.12.0" 2837 | source = "registry+https://github.com/rust-lang/crates.io-index" 2838 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" 2839 | 2840 | [[package]] 2841 | name = "unicase" 2842 | version = "1.4.2" 2843 | source = "registry+https://github.com/rust-lang/crates.io-index" 2844 | checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" 2845 | dependencies = [ 2846 | "version_check 0.1.5", 2847 | ] 2848 | 2849 | [[package]] 2850 | name = "unicase" 2851 | version = "2.6.0" 2852 | source = "registry+https://github.com/rust-lang/crates.io-index" 2853 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 2854 | dependencies = [ 2855 | "version_check 0.9.2", 2856 | ] 2857 | 2858 | [[package]] 2859 | name = "unicode-bidi" 2860 | version = "0.3.4" 2861 | source = "registry+https://github.com/rust-lang/crates.io-index" 2862 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 2863 | dependencies = [ 2864 | "matches", 2865 | ] 2866 | 2867 | [[package]] 2868 | name = "unicode-normalization" 2869 | version = "0.1.13" 2870 | source = "registry+https://github.com/rust-lang/crates.io-index" 2871 | checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" 2872 | dependencies = [ 2873 | "tinyvec", 2874 | ] 2875 | 2876 | [[package]] 2877 | name = "unicode-width" 2878 | version = "0.1.8" 2879 | source = "registry+https://github.com/rust-lang/crates.io-index" 2880 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 2881 | 2882 | [[package]] 2883 | name = "unicode-xid" 2884 | version = "0.2.1" 2885 | source = "registry+https://github.com/rust-lang/crates.io-index" 2886 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 2887 | 2888 | [[package]] 2889 | name = "url" 2890 | version = "1.7.2" 2891 | source = "registry+https://github.com/rust-lang/crates.io-index" 2892 | checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 2893 | dependencies = [ 2894 | "idna 0.1.5", 2895 | "matches", 2896 | "percent-encoding 1.0.1", 2897 | ] 2898 | 2899 | [[package]] 2900 | name = "url" 2901 | version = "2.1.1" 2902 | source = "registry+https://github.com/rust-lang/crates.io-index" 2903 | checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 2904 | dependencies = [ 2905 | "idna 0.2.0", 2906 | "matches", 2907 | "percent-encoding 2.1.0", 2908 | ] 2909 | 2910 | [[package]] 2911 | name = "vcpkg" 2912 | version = "0.2.10" 2913 | source = "registry+https://github.com/rust-lang/crates.io-index" 2914 | checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" 2915 | 2916 | [[package]] 2917 | name = "vec_map" 2918 | version = "0.8.2" 2919 | source = "registry+https://github.com/rust-lang/crates.io-index" 2920 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 2921 | 2922 | [[package]] 2923 | name = "version_check" 2924 | version = "0.1.5" 2925 | source = "registry+https://github.com/rust-lang/crates.io-index" 2926 | checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 2927 | 2928 | [[package]] 2929 | name = "version_check" 2930 | version = "0.9.2" 2931 | source = "registry+https://github.com/rust-lang/crates.io-index" 2932 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 2933 | 2934 | [[package]] 2935 | name = "want" 2936 | version = "0.0.4" 2937 | source = "registry+https://github.com/rust-lang/crates.io-index" 2938 | checksum = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" 2939 | dependencies = [ 2940 | "futures", 2941 | "log 0.4.11", 2942 | "try-lock 0.1.0", 2943 | ] 2944 | 2945 | [[package]] 2946 | name = "want" 2947 | version = "0.2.0" 2948 | source = "registry+https://github.com/rust-lang/crates.io-index" 2949 | checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 2950 | dependencies = [ 2951 | "futures", 2952 | "log 0.4.11", 2953 | "try-lock 0.2.3", 2954 | ] 2955 | 2956 | [[package]] 2957 | name = "want" 2958 | version = "0.3.0" 2959 | source = "registry+https://github.com/rust-lang/crates.io-index" 2960 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 2961 | dependencies = [ 2962 | "log 0.4.11", 2963 | "try-lock 0.2.3", 2964 | ] 2965 | 2966 | [[package]] 2967 | name = "wasi" 2968 | version = "0.9.0+wasi-snapshot-preview1" 2969 | source = "registry+https://github.com/rust-lang/crates.io-index" 2970 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2971 | 2972 | [[package]] 2973 | name = "wasm-bindgen" 2974 | version = "0.2.67" 2975 | source = "registry+https://github.com/rust-lang/crates.io-index" 2976 | checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" 2977 | dependencies = [ 2978 | "cfg-if", 2979 | "serde 1.0.114", 2980 | "serde_json", 2981 | "wasm-bindgen-macro", 2982 | ] 2983 | 2984 | [[package]] 2985 | name = "wasm-bindgen-backend" 2986 | version = "0.2.67" 2987 | source = "registry+https://github.com/rust-lang/crates.io-index" 2988 | checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0" 2989 | dependencies = [ 2990 | "bumpalo", 2991 | "lazy_static", 2992 | "log 0.4.11", 2993 | "proc-macro2", 2994 | "quote", 2995 | "syn", 2996 | "wasm-bindgen-shared", 2997 | ] 2998 | 2999 | [[package]] 3000 | name = "wasm-bindgen-futures" 3001 | version = "0.4.17" 3002 | source = "registry+https://github.com/rust-lang/crates.io-index" 3003 | checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699" 3004 | dependencies = [ 3005 | "cfg-if", 3006 | "js-sys", 3007 | "wasm-bindgen", 3008 | "web-sys", 3009 | ] 3010 | 3011 | [[package]] 3012 | name = "wasm-bindgen-macro" 3013 | version = "0.2.67" 3014 | source = "registry+https://github.com/rust-lang/crates.io-index" 3015 | checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2" 3016 | dependencies = [ 3017 | "quote", 3018 | "wasm-bindgen-macro-support", 3019 | ] 3020 | 3021 | [[package]] 3022 | name = "wasm-bindgen-macro-support" 3023 | version = "0.2.67" 3024 | source = "registry+https://github.com/rust-lang/crates.io-index" 3025 | checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556" 3026 | dependencies = [ 3027 | "proc-macro2", 3028 | "quote", 3029 | "syn", 3030 | "wasm-bindgen-backend", 3031 | "wasm-bindgen-shared", 3032 | ] 3033 | 3034 | [[package]] 3035 | name = "wasm-bindgen-shared" 3036 | version = "0.2.67" 3037 | source = "registry+https://github.com/rust-lang/crates.io-index" 3038 | checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092" 3039 | 3040 | [[package]] 3041 | name = "web-sys" 3042 | version = "0.3.44" 3043 | source = "registry+https://github.com/rust-lang/crates.io-index" 3044 | checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47" 3045 | dependencies = [ 3046 | "js-sys", 3047 | "wasm-bindgen", 3048 | ] 3049 | 3050 | [[package]] 3051 | name = "which" 3052 | version = "3.1.1" 3053 | source = "registry+https://github.com/rust-lang/crates.io-index" 3054 | checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" 3055 | dependencies = [ 3056 | "libc", 3057 | ] 3058 | 3059 | [[package]] 3060 | name = "winapi" 3061 | version = "0.2.8" 3062 | source = "registry+https://github.com/rust-lang/crates.io-index" 3063 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 3064 | 3065 | [[package]] 3066 | name = "winapi" 3067 | version = "0.3.9" 3068 | source = "registry+https://github.com/rust-lang/crates.io-index" 3069 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 3070 | dependencies = [ 3071 | "winapi-i686-pc-windows-gnu", 3072 | "winapi-x86_64-pc-windows-gnu", 3073 | ] 3074 | 3075 | [[package]] 3076 | name = "winapi-build" 3077 | version = "0.1.1" 3078 | source = "registry+https://github.com/rust-lang/crates.io-index" 3079 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 3080 | 3081 | [[package]] 3082 | name = "winapi-i686-pc-windows-gnu" 3083 | version = "0.4.0" 3084 | source = "registry+https://github.com/rust-lang/crates.io-index" 3085 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3086 | 3087 | [[package]] 3088 | name = "winapi-util" 3089 | version = "0.1.5" 3090 | source = "registry+https://github.com/rust-lang/crates.io-index" 3091 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 3092 | dependencies = [ 3093 | "winapi 0.3.9", 3094 | ] 3095 | 3096 | [[package]] 3097 | name = "winapi-x86_64-pc-windows-gnu" 3098 | version = "0.4.0" 3099 | source = "registry+https://github.com/rust-lang/crates.io-index" 3100 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3101 | 3102 | [[package]] 3103 | name = "winreg" 3104 | version = "0.7.0" 3105 | source = "registry+https://github.com/rust-lang/crates.io-index" 3106 | checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" 3107 | dependencies = [ 3108 | "winapi 0.3.9", 3109 | ] 3110 | 3111 | [[package]] 3112 | name = "ws2_32-sys" 3113 | version = "0.2.1" 3114 | source = "registry+https://github.com/rust-lang/crates.io-index" 3115 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 3116 | dependencies = [ 3117 | "winapi 0.2.8", 3118 | "winapi-build", 3119 | ] 3120 | 3121 | [[package]] 3122 | name = "yaml-rust" 3123 | version = "0.4.4" 3124 | source = "registry+https://github.com/rust-lang/crates.io-index" 3125 | checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" 3126 | dependencies = [ 3127 | "linked-hash-map 0.5.3", 3128 | ] 3129 | --------------------------------------------------------------------------------