Merge pull request #62 from garious/batch-events

Batch events
This commit is contained in:
Greg Fitzgerald 2018-03-09 17:37:02 -07:00 committed by GitHub
commit 1e07014f86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 122 additions and 593 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
Cargo.lock
/target/
**/*.rs.bk

482
Cargo.lock generated
View File

@ -1,482 +0,0 @@
[[package]]
name = "arrayref"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bincode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dtoa"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "either"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "generic-array"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memoffset"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "nodrop"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ring"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scopeguard"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2-asm"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "silk"
version = "0.3.3"
dependencies = [
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2-asm 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.12.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typenum"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "untrusted"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59796cc6cbbdc6bb319161349db0c3250ec73ec7fcb763a51065ec4e2e158552"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593"
"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "e928fecdb00fe608c96f83a012633383564e730962fc7a0b79225a6acf056798"
"checksum serde_derive 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "95f666a2356d87ce4780ea15b14b13532785579a5cad2dcba5292acc75f6efe2"
"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8"
"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39"
"checksum sha2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7daca11f2fdb8559c4f6c588386bed5e2ad4b6605c1442935a7f08144a918688"
"checksum sha2-asm 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e319010fd740857efd4428b8ee1b74f311aeb0fda1ece174a9bad6741182d26"
"checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -9,6 +9,7 @@ use transaction::{Condition, Transaction};
use signature::{KeyPair, PublicKey, Signature};
use mint::Mint;
use historian::{reserve_signature, Historian};
use logger::Signal;
use std::sync::mpsc::SendError;
use std::collections::{HashMap, HashSet};
use std::result;
@ -61,10 +62,12 @@ impl Accountant {
// fields are the same. That entry should be treated as a deposit, not a
// transfer to oneself.
let entry1 = entries.next().unwrap();
acc.process_verified_event(&entry1.event, true).unwrap();
acc.process_verified_event(&entry1.events[0], true).unwrap();
for entry in entries {
acc.process_verified_event(&entry.event, false).unwrap();
for event in entry.events {
acc.process_verified_event(&event, false).unwrap();
}
}
acc
}
@ -94,7 +97,10 @@ impl Accountant {
}
self.process_verified_transaction(&tr, false)?;
if let Err(SendError(_)) = self.historian.sender.send(Event::Transaction(tr)) {
if let Err(SendError(_)) = self.historian
.sender
.send(Signal::Event(Event::Transaction(tr)))
{
return Err(AccountingError::SendError);
}
@ -241,7 +247,6 @@ impl Accountant {
fn process_verified_event(self: &mut Self, event: &Event, allow_deposits: bool) -> Result<()> {
match *event {
Event::Tick => Ok(()),
Event::Transaction(ref tr) => self.process_verified_transaction(tr, allow_deposits),
Event::Signature { from, tx_sig, .. } => self.process_verified_sig(from, tx_sig),
Event::Timestamp { from, dt, .. } => self.process_verified_timestamp(from, dt),

View File

@ -93,11 +93,13 @@ impl AccountantStub {
self.socket.recv_from(&mut buf)?;
let resp = deserialize(&buf).expect("deserialize signature");
if let Response::Entries { entries } = resp {
for Entry { id, event, .. } in entries {
for Entry { id, events, .. } in entries {
self.last_id = Some(id);
if let Some(sig) = event.get_signature() {
if sig == *wait_sig {
return Ok(());
for event in events {
if let Some(sig) = event.get_signature() {
if sig == *wait_sig {
return Ok(());
}
}
}
}

View File

@ -4,7 +4,7 @@ extern crate silk;
use silk::mint::Mint;
use silk::event::Event;
use silk::transaction::Transaction;
use silk::log::create_entries;
use silk::entry::create_entry;
use silk::signature::{KeyPair, KeyPairUtil, PublicKey};
use silk::hash::Hash;
use std::io::stdin;
@ -14,17 +14,17 @@ fn transfer(from: &KeyPair, (to, tokens): (PublicKey, i64), last_id: Hash) -> Ev
}
fn main() {
let alice = (KeyPair::new().pubkey(), 200);
let bob = (KeyPair::new().pubkey(), 100);
let mint: Mint = serde_json::from_reader(stdin()).unwrap();
let mut entries = mint.create_entries();
let from = mint.keypair();
let seed = mint.seed();
let mut events = mint.create_events();
events.push(transfer(&from, alice, seed));
events.push(transfer(&from, bob, seed));
let alice = (KeyPair::new().pubkey(), 200);
let bob = (KeyPair::new().pubkey(), 100);
let events = vec![transfer(&from, alice, seed), transfer(&from, bob, seed)];
entries.push(create_entry(&seed, 0, events));
for entry in create_entries(&seed, events) {
for entry in entries {
println!("{}", serde_json::to_string(&entry).unwrap());
}
}

View File

@ -4,6 +4,7 @@ use silk::historian::Historian;
use silk::hash::Hash;
use silk::entry::Entry;
use silk::log::verify_slice;
use silk::logger::Signal;
use silk::signature::{KeyPair, KeyPairUtil};
use silk::transaction::Transaction;
use silk::event::Event;
@ -11,12 +12,12 @@ use std::thread::sleep;
use std::time::Duration;
use std::sync::mpsc::SendError;
fn create_log(hist: &Historian, seed: &Hash) -> Result<(), SendError<Event>> {
fn create_log(hist: &Historian, seed: &Hash) -> Result<(), SendError<Signal>> {
sleep(Duration::from_millis(15));
let keypair = KeyPair::new();
let tr = Transaction::new(&keypair, keypair.pubkey(), 42, *seed);
let event0 = Event::Transaction(tr);
hist.sender.send(event0)?;
let signal0 = Signal::Event(Event::Transaction(tr));
hist.sender.send(signal0)?;
sleep(Duration::from_millis(10));
Ok(())
}

View File

@ -5,7 +5,7 @@ use event::Event;
pub struct Entry {
pub num_hashes: u64,
pub id: Hash,
pub event: Event,
pub events: Vec<Event>,
}
impl Entry {
@ -15,51 +15,61 @@ impl Entry {
Entry {
num_hashes,
id: *id,
event: Event::Tick,
events: vec![],
}
}
/// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times.
/// If the event is not a Tick, then hash that as well.
pub fn verify(&self, start_hash: &Hash) -> bool {
if !self.event.verify() {
return false;
for event in &self.events {
if !event.verify() {
return false;
}
}
self.id == next_hash(start_hash, self.num_hashes, &self.event)
self.id == next_hash(start_hash, self.num_hashes, &self.events)
}
}
/// Creates the hash 'num_hashes' after start_hash. If the event contains
/// signature, the final hash will be a hash of both the previous ID and
/// the signature.
pub fn next_hash(start_hash: &Hash, num_hashes: u64, event: &Event) -> Hash {
pub fn next_hash(start_hash: &Hash, num_hashes: u64, events: &[Event]) -> Hash {
let mut id = *start_hash;
let sig = event.get_signature();
let start_index = if sig.is_some() { 1 } else { 0 };
for _ in start_index..num_hashes {
for _ in 1..num_hashes {
id = hash(&id);
}
if let Some(sig) = sig {
id = extend_and_hash(&id, &sig);
// Hash all the event data
let mut hash_data = vec![];
for event in events {
let sig = event.get_signature();
if let Some(sig) = sig {
hash_data.extend_from_slice(&sig);
}
}
if !hash_data.is_empty() {
return extend_and_hash(&id, &hash_data);
}
id
}
/// Creates the next Entry 'num_hashes' after 'start_hash'.
pub fn create_entry(start_hash: &Hash, cur_hashes: u64, event: Event) -> Entry {
let sig = event.get_signature();
let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 };
let id = next_hash(start_hash, 0, &event);
pub fn create_entry(start_hash: &Hash, cur_hashes: u64, events: Vec<Event>) -> Entry {
let num_hashes = cur_hashes + if events.is_empty() { 0 } else { 1 };
let id = next_hash(start_hash, 0, &events);
Entry {
num_hashes,
id,
event,
events,
}
}
/// Creates the next Tick Entry 'num_hashes' after 'start_hash'.
pub fn create_entry_mut(start_hash: &mut Hash, cur_hashes: &mut u64, event: Event) -> Entry {
let entry = create_entry(start_hash, *cur_hashes, event);
pub fn create_entry_mut(start_hash: &mut Hash, cur_hashes: &mut u64, events: Vec<Event>) -> Entry {
let entry = create_entry(start_hash, *cur_hashes, events);
*start_hash = entry.id;
*cur_hashes = 0;
entry
@ -67,20 +77,24 @@ pub fn create_entry_mut(start_hash: &mut Hash, cur_hashes: &mut u64, event: Even
/// Creates the next Tick Entry 'num_hashes' after 'start_hash'.
pub fn next_tick(start_hash: &Hash, num_hashes: u64) -> Entry {
let event = Event::Tick;
Entry {
num_hashes,
id: next_hash(start_hash, num_hashes, &event),
event,
id: next_hash(start_hash, num_hashes, &[]),
events: vec![],
}
}
#[cfg(test)]
mod tests {
use super::*;
use hash::hash;
use signature::{KeyPair, KeyPairUtil};
use transaction::Transaction;
use event::Event;
use entry::create_entry;
#[test]
fn test_event_verify() {
fn test_entry_verify() {
let zero = Hash::default();
let one = hash(&zero);
assert!(Entry::new_tick(0, &zero).verify(&zero)); // base case
@ -89,6 +103,23 @@ mod tests {
assert!(!next_tick(&zero, 1).verify(&one)); // inductive step, bad
}
#[test]
fn test_event_reorder_attack() {
let zero = Hash::default();
// First, verify entries
let keypair = KeyPair::new();
let tr0 = Event::Transaction(Transaction::new(&keypair, keypair.pubkey(), 0, zero));
let tr1 = Event::Transaction(Transaction::new(&keypair, keypair.pubkey(), 1, zero));
let mut e0 = create_entry(&zero, 0, vec![tr0.clone(), tr1.clone()]);
assert!(e0.verify(&zero));
// Next, swap two events and ensure verification fails.
e0.events[0] = tr1; // <-- attack
e0.events[1] = tr0;
assert!(!e0.verify(&zero));
}
#[test]
fn test_next_tick() {
let zero = Hash::default();

View File

@ -5,14 +5,8 @@ use transaction::Transaction;
use chrono::prelude::*;
use bincode::serialize;
/// When 'event' is Tick, the event represents a simple clock tick, and exists for the
/// sole purpose of improving the performance of event log verification. A tick can
/// be generated in 'num_hashes' hashes and verified in 'num_hashes' hashes. By logging
/// a hash alongside the tick, each tick and be verified in parallel using the 'id'
/// of the preceding tick to seed its hashing.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum Event {
Tick,
Transaction(Transaction<i64>),
Signature {
from: PublicKey,
@ -40,7 +34,6 @@ impl Event {
// TODO: Rename this to transaction_signature().
pub fn get_signature(&self) -> Option<Signature> {
match *self {
Event::Tick => None,
Event::Transaction(ref tr) => Some(tr.sig),
Event::Signature { .. } => None,
Event::Timestamp { .. } => None,
@ -49,7 +42,6 @@ impl Event {
pub fn verify(&self) -> bool {
match *self {
Event::Tick => true,
Event::Transaction(ref tr) => tr.verify(),
Event::Signature { from, tx_sig, sig } => sig.verify(&from, &tx_sig),
Event::Timestamp { from, dt, sig } => sig.verify(&from, &serialize(&dt).unwrap()),

View File

@ -7,12 +7,11 @@ use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::time::Instant;
use hash::{hash, Hash};
use entry::Entry;
use logger::{ExitReason, Logger};
use logger::{ExitReason, Logger, Signal};
use signature::Signature;
use event::Event;
pub struct Historian {
pub sender: SyncSender<Event>,
pub sender: SyncSender<Signal>,
pub receiver: Receiver<Entry>,
pub thread_hdl: JoinHandle<ExitReason>,
pub signatures: HashSet<Signature>,
@ -38,7 +37,7 @@ impl Historian {
fn create_logger(
start_hash: Hash,
ms_per_tick: Option<u64>,
receiver: Receiver<Event>,
receiver: Receiver<Signal>,
sender: SyncSender<Entry>,
) -> JoinHandle<ExitReason> {
spawn(move || {
@ -69,7 +68,6 @@ pub fn reserve_signature(sigs: &mut HashSet<Signature>, sig: &Signature) -> bool
mod tests {
use super::*;
use log::*;
use event::*;
use std::thread::sleep;
use std::time::Duration;
@ -78,11 +76,11 @@ mod tests {
let zero = Hash::default();
let hist = Historian::new(&zero, None);
hist.sender.send(Event::Tick).unwrap();
hist.sender.send(Signal::Tick).unwrap();
sleep(Duration::new(0, 1_000_000));
hist.sender.send(Event::Tick).unwrap();
hist.sender.send(Signal::Tick).unwrap();
sleep(Duration::new(0, 1_000_000));
hist.sender.send(Event::Tick).unwrap();
hist.sender.send(Signal::Tick).unwrap();
let entry0 = hist.receiver.recv().unwrap();
let entry1 = hist.receiver.recv().unwrap();
@ -106,7 +104,7 @@ mod tests {
let zero = Hash::default();
let hist = Historian::new(&zero, None);
drop(hist.receiver);
hist.sender.send(Event::Tick).unwrap();
hist.sender.send(Signal::Tick).unwrap();
assert_eq!(
hist.thread_hdl.join().unwrap(),
ExitReason::SendDisconnected
@ -126,7 +124,7 @@ mod tests {
let zero = Hash::default();
let hist = Historian::new(&zero, Some(20));
sleep(Duration::from_millis(30));
hist.sender.send(Event::Tick).unwrap();
hist.sender.send(Signal::Tick).unwrap();
drop(hist.sender);
let entries: Vec<Entry> = hist.receiver.iter().collect();

View File

@ -14,25 +14,16 @@
/// was generated by the fastest processor at the time the entry was logged.
use hash::Hash;
use entry::{create_entry_mut, next_tick, Entry};
use event::Event;
use entry::{next_tick, Entry};
use rayon::prelude::*;
/// Verifies the hashes and counts of a slice of events are all consistent.
pub fn verify_slice(events: &[Entry], start_hash: &Hash) -> bool {
pub fn verify_slice(entries: &[Entry], start_hash: &Hash) -> bool {
let genesis = [Entry::new_tick(Default::default(), start_hash)];
let event_pairs = genesis.par_iter().chain(events).zip(events);
let event_pairs = genesis.par_iter().chain(entries).zip(entries);
event_pairs.all(|(x0, x1)| x1.verify(&x0.id))
}
pub fn create_entries(start_hash: &Hash, events: Vec<Event>) -> Vec<Entry> {
let mut id = *start_hash;
events
.into_iter()
.map(|event| create_entry_mut(&mut id, &mut 0, event))
.collect()
}
/// Create a vector of Ticks of length 'len' from 'start_hash' hash and 'num_hashes'.
pub fn next_ticks(start_hash: &Hash, num_hashes: u64, len: usize) -> Vec<Entry> {
let mut id = *start_hash;
@ -48,8 +39,6 @@ pub fn next_ticks(start_hash: &Hash, num_hashes: u64, len: usize) -> Vec<Entry>
#[cfg(test)]
mod tests {
use super::*;
use signature::{KeyPair, KeyPairUtil};
use transaction::Transaction;
use hash::hash;
#[test]
@ -65,26 +54,6 @@ mod tests {
bad_ticks[1].id = one;
assert!(!verify_slice(&bad_ticks, &zero)); // inductive step, bad
}
#[test]
fn test_reorder_attack() {
let zero = Hash::default();
// First, verify entries
let keypair = KeyPair::new();
let tr0 = Transaction::new(&keypair, keypair.pubkey(), 0, zero);
let tr1 = Transaction::new(&keypair, keypair.pubkey(), 1, zero);
let events = vec![Event::Transaction(tr0), Event::Transaction(tr1)];
let mut entries = create_entries(&zero, events);
assert!(verify_slice(&entries, &zero));
// Next, swap two events and ensure verification fails.
let event0 = entries[0].event.clone();
let event1 = entries[1].event.clone();
entries[0].event = event1;
entries[1].event = event0;
assert!(!verify_slice(&entries, &zero));
}
}
#[cfg(all(feature = "unstable", test))]

View File

@ -7,11 +7,17 @@
use std::sync::mpsc::{Receiver, SyncSender, TryRecvError};
use std::time::{Duration, Instant};
use std::mem;
use hash::Hash;
use entry::{create_entry_mut, Entry};
use event::Event;
use serde_json;
pub enum Signal {
Tick,
Event(Event),
}
#[derive(Debug, PartialEq, Eq)]
pub enum ExitReason {
RecvDisconnected,
@ -20,25 +26,28 @@ pub enum ExitReason {
pub struct Logger {
pub sender: SyncSender<Entry>,
pub receiver: Receiver<Event>,
pub receiver: Receiver<Signal>,
pub last_id: Hash,
pub events: Vec<Event>,
pub num_hashes: u64,
pub num_ticks: u64,
}
impl Logger {
pub fn new(receiver: Receiver<Event>, sender: SyncSender<Entry>, start_hash: Hash) -> Self {
pub fn new(receiver: Receiver<Signal>, sender: SyncSender<Entry>, start_hash: Hash) -> Self {
Logger {
receiver,
sender,
last_id: start_hash,
events: vec![],
num_hashes: 0,
num_ticks: 0,
}
}
pub fn log_event(&mut self, event: Event) -> Result<Entry, ExitReason> {
let entry = create_entry_mut(&mut self.last_id, &mut self.num_hashes, event);
pub fn log_entry(&mut self) -> Result<Entry, ExitReason> {
let events = mem::replace(&mut self.events, vec![]);
let entry = create_entry_mut(&mut self.last_id, &mut self.num_hashes, events);
println!("{}", serde_json::to_string(&entry).unwrap());
Ok(entry)
}
@ -51,18 +60,23 @@ impl Logger {
loop {
if let Some(ms) = ms_per_tick {
if epoch.elapsed() > Duration::from_millis((self.num_ticks + 1) * ms) {
self.log_event(Event::Tick)?;
self.log_entry()?;
self.num_ticks += 1;
}
}
match self.receiver.try_recv() {
Ok(event) => {
let entry = self.log_event(event)?;
self.sender
.send(entry)
.or(Err(ExitReason::SendDisconnected))?;
}
Ok(signal) => match signal {
Signal::Tick => {
let entry = self.log_entry()?;
self.sender
.send(entry)
.or(Err(ExitReason::SendDisconnected))?;
}
Signal::Event(event) => {
self.events.push(event);
}
},
Err(TryRecvError::Empty) => return Ok(()),
Err(TryRecvError::Disconnected) => return Err(ExitReason::RecvDisconnected),
};

View File

@ -4,7 +4,7 @@ use event::Event;
use transaction::Transaction;
use signature::{KeyPair, KeyPairUtil, PublicKey};
use entry::Entry;
use log::create_entries;
use entry::create_entry;
use hash::{hash, Hash};
use ring::rand::SystemRandom;
use untrusted::Input;
@ -44,11 +44,13 @@ impl Mint {
pub fn create_events(&self) -> Vec<Event> {
let keypair = self.keypair();
let tr = Transaction::new(&keypair, self.pubkey(), self.tokens, self.seed());
vec![Event::Tick, Event::Transaction(tr)]
vec![Event::Transaction(tr)]
}
pub fn create_entries(&self) -> Vec<Entry> {
create_entries(&self.seed(), self.create_events())
let e0 = create_entry(&self.seed(), 0, vec![]);
let e1 = create_entry(&e0.id, 0, self.create_events());
vec![e0, e1]
}
}
@ -60,11 +62,8 @@ mod tests {
#[test]
fn test_create_events() {
let mut events = Mint::new(100).create_events().into_iter();
assert_eq!(events.next().unwrap(), Event::Tick);
if let Event::Transaction(tr) = events.next().unwrap() {
assert_eq!(tr.from, tr.to);
} else {
assert!(false);
}
assert_eq!(events.next(), None);
}