Commit Graph

36 Commits

Author SHA1 Message Date
Wladimir J. van der Laan
b83cab5441
Merge #14838: Use const in COutPoint class
cf4b0327ed92ca8a1533cdf6c2b0015fd9b56397 Use std::numeric_limits<UNSIGNED>::max()) instead of (UNSIGNED)-1 (practicalswift)
6b82fc59eb19004e54f910261a40d5e1b9e44b42 Use const in COutPoint class (Hennadii Stepanov)

Pull request description:

  Refactoring:
  - all cases of using `(uint32_t) -1` in `COutPoint` class are replaced with const;
  - also all remaining instances of `(UNSIGNED)-1` transformed to `std::numeric_limits<UNSIGNED>::max()` (by @practicalswift).

Tree-SHA512: fc7fe9838b6e5136d8b97ea3d6f64c4aaa1215f4369832df432cab017396620bb6e30520a64180ceab6de222562ac11eab243a78dfa5a658ba018835a34caa19
2021-07-08 11:57:10 -05:00
Kittywhiskers Van Gogh
680067ce7a
merge #19954: Complete the BIP155 implementation and upgrade to TORv3 2021-05-29 23:24:52 +03:00
UdjinM6
64d4a48a09
Some missing non-Dash-specifc serializations 2021-05-28 11:39:25 +03:00
UdjinM6
cb0eeee0df
partial merge #9039: OverrideStream changes from Get rid of nType and nVersion commit 2021-05-27 21:49:53 +03:00
UdjinM6
ade894eb0f
partial merge #9039: OverrideStream changes from Make nType and nVersion private and sometimes const commit 2021-05-27 21:49:53 +03:00
Kittywhiskers Van Gogh
05e5ee1be6
partial merge #8149: import OverrideStream from "BIP144: Serialization, hashes, relay (sender side)" 2021-05-27 21:49:48 +03:00
Pieter Wuille
ec71097801
Merge #12683: Fix more constness violations in serialization code
172f5fa738 Support deserializing into temporaries (Pieter Wuille)
2761bca997 Merge READWRITEMANY into READWRITE (Pieter Wuille)

Pull request description:

  This is another fragment of improvements from #10785.

  The current serialization code does not support serializing/deserializing from/to temporaries (like `s >> CFlatData(script)`). As a result, there are many invocations of the `REF` macro which in addition to changing the reference type also changes the constness. This is unnecessary in C++11 as we can use rvalue references now instead.

  The first commit is an extra simplification we can make that removes the duplication of code between `READWRITE` and `READWRITEMANY` (and related functions).

Tree-SHA512: babfa9cb268cc3bc39917e4f0a90e4651c33d85032161e16547a07f3b257b7ca7940e0cbfd69f09439d26fafbb1a6cf6359101043407e2c7aeececf7f20b6eed
2020-12-17 05:07:07 +03:00
pasta
c49e506176 scripted-diff: Merge #13753: Remove trailing whitespaces
-BEGIN VERIFY SCRIPT-

sed --in-place'' --regexp-extended 's/[[:space:]]+$//g' $(git grep -I --files-with-matches --extended-regexp '[[:space:]]+$' -- src test  ':!*.svg' ':!src/crypto/sha256_sse4*' ':!src/leveldb' ':!src/qt/locale' ':!src/secp256k1' ':!src/univalue')

-END VERIFY SCRIPT-

Signed-off-by: pasta <pasta@dashboost.org>
2020-07-28 20:23:12 -05:00
Wladimir J. van der Laan
17929071d4 Merge #12254: BIP 158: Compact Block Filters for Light Clients
254c85b68794ada713dbdae415db72adf5fcbaf3 bench: Benchmark GCS filter creation and matching. (Jim Posen)
f33b717a85363e067316c133a542559d2f4aaeca blockfilter: Optimization on compilers with int128 support. (Jim Posen)
97b64d67daf0336dfb64b132f3e4d6a4c1967da4 blockfilter: Unit test against BIP 158 test vectors. (Jim Posen)
a4afb9cadbaecb0676e6475ab8d32a52faecb47a blockfilter: Additional helper methods to compute hash and header. (Jim Posen)
cd09c7925b5af4104834971cfe072251e3ac2bda blockfilter: Serialization methods on BlockFilter. (Jim Posen)
c1855f6052aca806fdb51be01b30dfeee8b55f40 blockfilter: Construction of basic block filters. (Jim Posen)
53e7874e079f9ddfe8b176f11d46e6b59c7283d5 blockfilter: Simple test for GCSFilter construction and Match. (Jim Posen)
558c536e35a25594881693e6ff01d275c88d7af1 blockfilter: Implement GCSFilter Match methods. (Jim Posen)
cf70b550054eed36f194eaa13f4a9cb31e32df38 blockfilter: Implement GCSFilter constructors. (Jim Posen)
c454f0ac63c6028f54c7eb51683b3ccdb475b19b blockfilter: Declare GCSFilter class for BIP 158 impl. (Jim Posen)
9b622dc72279b027c59d6541cddff53800fc689b streams: Unit tests for BitStreamReader and BitStreamWriter. (Jim Posen)
fe943f99bf0a2bbb12e30bc4803c0337e3c95b93 streams: Implement BitStreamReader/Writer classes. (Jim Posen)
87f2d9ee43a9220076b1959d1ca65245d9591be9 streams: Unit test for VectorReader class. (Jim Posen)
947133dec92cd25ec2b3358c09b8614ba6fb40d4 streams: Create VectorReader stream interface for vectors. (Jim Posen)

Pull request description:

  This implements the compact block filter construction in [BIP 158](https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki). The code is not used anywhere in the Bitcoin Core code base yet. The next step towards [BIP 157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) support would be to create an indexing module similar to `TxIndex` that constructs the basic and extended filters for each validated block.

  ### Filter Sizes

  [Here](https://gateway.ipfs.io/ipfs/QmRqaAAQZ5ZX5eqxP7J2R1MzFrc2WDdKSWJEKtQzyawqog) is a CSV of filter sizes for blocks in the main chain.

  As you can see below, the ratio of filter size to block size drops after the first ~150,000 blocks:

  ![filter_sizes](https://user-images.githubusercontent.com/881253/42900589-299772d4-8a7e-11e8-886d-0d4f3f4fbe44.png)

  The reason for the relatively large filter sizes is that Golomb-coded sets only achieve good compression with a sufficient number of elements. Empirically, the average element size with 100 elements is 14% larger than with 10,000 elements.

  The ratio of filter size to block size is computed without witness data for basic filters. Here is a summary table of filter size ratios *for blocks after height 150,000*:

  | Stat | Filter Type |
  |-------|--------------|
  | Weighted Size Ratio Mean | 0.0198 |
  | Size Ratio Mean | 0.0224 |
  | Size Ratio Std Deviation | 0.0202 |
  | Mean Element Size (bits) | 21.145 |
  | Approx Theoretical Min Element Size (bits) | 21.025 |

Tree-SHA512: 2d045fbfc3fc45490ecb9b08d2f7e4dbbe7cd8c1c939f06bbdb8e8aacfe4c495cdb67c820e52520baebbf8a8305a0efd8e59d3fa8e367574a4b830509a39223f
2020-06-13 14:08:18 -05:00
MarcoFalke
0d4d3c3254
Merge #12283: Fix typos
1340eda3b7 Fix typos (practicalswift)

Pull request description:

  Fix typos.

Tree-SHA512: 533a136831387ef26e9a74ba078437496bee38cc026da73fa9e6f6e7f4d5665eccac24cf3ef05e6d3af1329a1214f5ce71b039ddb8378b074e6d4408b8701f95
2020-06-10 18:32:43 -05:00
PastaPastaPasta
8a1ec935a0
Backport 11651 (#3358)
* scripted-diff: Replace #include "" with #include <> (ryanofsky)

-BEGIN VERIFY SCRIPT-
for f in \
  src/*.cpp \
  src/*.h \
  src/bench/*.cpp \
  src/bench/*.h \
  src/compat/*.cpp \
  src/compat/*.h \
  src/consensus/*.cpp \
  src/consensus/*.h \
  src/crypto/*.cpp \
  src/crypto/*.h \
  src/crypto/ctaes/*.h \
  src/policy/*.cpp \
  src/policy/*.h \
  src/primitives/*.cpp \
  src/primitives/*.h \
  src/qt/*.cpp \
  src/qt/*.h \
  src/qt/test/*.cpp \
  src/qt/test/*.h \
  src/rpc/*.cpp \
  src/rpc/*.h \
  src/script/*.cpp \
  src/script/*.h \
  src/support/*.cpp \
  src/support/*.h \
  src/support/allocators/*.h \
  src/test/*.cpp \
  src/test/*.h \
  src/wallet/*.cpp \
  src/wallet/*.h \
  src/wallet/test/*.cpp \
  src/wallet/test/*.h \
  src/zmq/*.cpp \
  src/zmq/*.h
do
  base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f
done
-END VERIFY SCRIPT-

Signed-off-by: Pasta <pasta@dashboost.org>

* scripted-diff: Replace #include "" with #include <> (Dash Specific)

-BEGIN VERIFY SCRIPT-
for f in \
  src/bls/*.cpp \
  src/bls/*.h \
  src/evo/*.cpp \
  src/evo/*.h \
  src/governance/*.cpp \
  src/governance/*.h \
  src/llmq/*.cpp \
  src/llmq/*.h \
  src/masternode/*.cpp \
  src/masternode/*.h \
  src/privatesend/*.cpp \
  src/privatesend/*.h
do
  base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f
done
-END VERIFY SCRIPT-

Signed-off-by: Pasta <pasta@dashboost.org>

* build: Remove -I for everything but project root

Remove -I from build system for everything but the project root,
and built-in dependencies.

Signed-off-by: Pasta <pasta@dashboost.org>

# Conflicts:
#	src/Makefile.test.include

* qt: refactor: Use absolute include paths in .ui files

* qt: refactor: Changes to make include paths absolute

This makes all include paths in the GUI absolute.

Many changes are involved as every single source file in
src/qt/ assumes to be able to use relative includes.

Signed-off-by: Pasta <pasta@dashboost.org>

# Conflicts:
#	src/qt/dash.cpp
#	src/qt/optionsmodel.cpp
#	src/qt/test/rpcnestedtests.cpp

* test: refactor: Use absolute include paths for test data files

* Recommend #include<> syntax in developer notes

* refactor: Include obj/build.h instead of build.h

* END BACKPORT #11651 Remove trailing whitespace causing travis failure

* fix backport 11651

Signed-off-by: Pasta <pasta@dashboost.org>

* More of 11651

* fix blockchain.cpp

Signed-off-by: pasta <pasta@dashboost.org>

* Add missing "qt/" in includes

* Add missing "test/" in includes

* Fix trailing whitespaces

Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-20 01:46:56 +03:00
PastaPastaPasta
52a6c4e336
Apply suggestions from code review
Co-Authored-By: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-02-08 23:33:25 -06:00
Wladimir J. van der Laan
2a018f8807
Merge #11221: Refactor: simpler read
9db9d62 Refactor: make the read function simpler (gnuser)

Pull request description:

Tree-SHA512: 5a80cc1b841488323d421e6a40b245d149cab1988247aed6cc7468dcc042d3df15b6711f25e40ff16e03ac21de36adbaa1d8da61ccdb94f97c8b70c24a5eedc5
2020-02-08 23:33:25 -06:00
Wladimir J. van der Laan
49825231fb
Merge #10839: Don't use pass by reference to const for cheaply-copied types (bool, char, etc.)
99ba0c3 Don't use pass by reference to const for cheaply-copied types (bool, char, etc.). (practicalswift)

Pull request description:

  Don't use pass by reference to const for cheaply-copied types (`bool`, `char`, etc.).

Tree-SHA512: ccad5e2695dff0b3d6de3e713ff3448f2981168cdac72d73bee10ad346b9919d8d4d588933369e54657a244b8b222fa0bef919bc56d983e1fa64b2004e51b225
2020-01-31 07:43:43 -06:00
Pieter Wuille
d6c4485412 Merge #11351: Refactor: Modernize disallowed copy constructors/assignment
2a07f878a Refactor: Modernize disallowed copy constructors/assignment (Dan Raviv)

Pull request description:

  Use C++11's better capability of expressing an interface of a non-copyable class by publicly deleting its copy ctor and assignment operator instead of just declaring them private.

Tree-SHA512: 878f446be5a136bb2a90643aaeaca62948b575e6ef71ccc5b4b8f373e66f36ced00665128f36504e0ccfee639863d969329c4276154ef9f2a9de9137f0801e01
2020-01-11 18:22:25 -06:00
MarcoFalke
8302bd5479 Merge #9964: Add const to methods that do not modify the object for which it is called
6e8c48dc5 Add const to methods that do not modify the object for which it is called (practicalswift)

Pull request description:

Tree-SHA512: a6888111ba16fb796e320e60806e1a77d36f545989b5405dc7319992291800109eab0b8e8c286b784778f41f1ff5289e7cb6b4afd7aec77f385fbcafc02cffc1
2020-01-02 16:16:55 -06:00
MarcoFalke
0486e5796f
Merge #11155: Trivial: Documentation fixes for CVectorWriter ctors
37c4362f2 Trivial: Documentation fixes for CVectorWriter ctors (danra)

Pull request description:

Tree-SHA512: 13aef27f6b38dc276db6616d13e243a5413acf3a3ece5a52578c07b97a5bc9da337e7e230fcdb91727ec88b199844fd9aa3a88e7d96c911c119c91070a892ba1
2020-01-01 22:31:14 -06:00
Pasta
1a0d52814e
#10483 scripted-diff: Use the C++11 keyword nullptr to denote the pointer literal instead of the macro NULL
-BEGIN VERIFY SCRIPT-
sed -i 's/\<NULL\>/nullptr/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h src/qt/*/*.cpp src/qt/*/*.h src/wallet/*/*.cpp src/wallet/*/*.h src/support/allocators/*.h
sed -i 's/Prefer nullptr, otherwise SAFECOOKIE./Prefer NULL, otherwise SAFECOOKIE./g' src/torcontrol.cpp
sed -i 's/tor: Using nullptr authentication/tor: Using NULL authentication/g' src/torcontrol.cpp
sed -i 's/METHODS=nullptr/METHODS=NULL/g' src/test/torcontrol_tests.cpp src/torcontrol.cpp
sed -i 's/nullptr certificates/NULL certificates/g' src/qt/paymentserver.cpp
sed -i 's/"nullptr"/"NULL"/g' src/torcontrol.cpp src/test/torcontrol_tests.cpp
-END VERIFY SCRIPT-

Signed-off-by: Pasta <pasta@dashboost.org>
2019-08-12 09:07:03 -05:00
Pieter Wuille
526036ead8
Merge #9804: Fixes subscript 0 (&var[0]) where should use (var.data()) instead.
30ac7688e Fix subscript[0] potential bugs in key.cpp (Jeremy Rubin)
4b1c0f2e2 Remove unnecessary branches in utilstrencodings string constructors. (Jeremy Rubin)
e19db7b5a Fix subscript[0] in utilstrencodings.cpp (Jeremy Rubin)
bc2e7fd98 Fix subscript[0] in streams.h (Jeremy Rubin)
4cac0d1e0 Fix subscript[0] in validation.cpp (Jeremy Rubin)
ac658e55f Fix subscript[0] in torcontrol (Jeremy Rubin)
b6856ebed Fix subscript[0] in netaddress.cpp (Jeremy Rubin)
361d95265 Fix subscript[0] in base58.cpp (Jeremy Rubin)
6896dbf16 Cleanup (safe, it was checked) subscript[0] in MurmurHash3 (and cleanup MurmurHash3 to be more clear). (Jeremy Rubin)
96f2119e6 Fix subscript[0] in compressor.cpp (Jeremy Rubin)
500710bd2 Fix 2 subscript[0] bugs in pubkey.cpp, and eliminate one extra size check (Jeremy Rubin)
e0451e3e2 Fix subscript[0] bug in net.cpp if GetGroup returns a 0-sized vector (Jeremy Rubin)

Tree-SHA512: 5b9103652cf8c615bd8f4f32b3573d291d6b67c39e0308ce00100bc6625f346e8e016b4c999f4f34f5c37ae059490a83c3b513deb21f838af785227d06e02362
2019-07-17 19:01:41 -05:00
Wladimir J. van der Laan
dd91bd7b3a
Merge #9911: Wshadow: various gcc fixes
d7f80b6 Rename first iterator to prevent shadowing. (Pavel Janík)
b42ff60 Fix shadowing of local variables. (Pavel Janík)
c4b60b3 Make some global variables less-global (static) (Pavel Janík)
bb2aaee Prevent -Wshadow warnings with gcc versions 4.8.5, 5.3.1 and 6.2.1. (Pavel Janík)

Tree-SHA512: 3aea4e28146c8f2a31351c6e2b0cce88b6f1e567a0ea0e6131624453e7193d0904e30d81b1439d8c69e281cf0e369b895851fb882ae48d5967b5c2e2c227404e
2019-05-06 14:51:45 -05:00
Wladimir J. van der Laan
3d3443b6a9
Merge #8808: Do not shadow variables (gcc set)
ad1ae7a Check and enable -Wshadow by default. (Pavel Janík)
9de90bb Do not shadow variables (gcc set) (Pavel Janík)

Tree-SHA512: 9517feb423dc8ddd63896016b25324673bfbe0bffa97f22996f59d7a3fcbdc2ebf2e43ac02bc067546f54e293e9b2f2514be145f867321e9031f895c063d9fb8
2019-02-01 00:41:12 -06:00
Alexander Block
dadfc45b15 Add size() method to CVectorWriter
Needed by CMasternodePing
2018-01-17 17:27:24 +01:00
Pieter Wuille
5c0b55a7c0 Merge #9128: net: Decouple CConnman and message serialization
c7be56d net: push only raw data into CConnman (Cory Fields)
2ec935d net: add CVectorWriter and CNetMsgMaker (Cory Fields)
b7695c2 net: No need to check individually for disconnection anymore (Cory Fields)
fedea8a net: don't send any messages before handshake or after requested disconnect (Cory Fields)
d74e352 net: Set feelers to disconnect at the end of the version message (Cory Fields)
2018-01-17 17:27:22 +01:00
Wladimir J. van der Laan
19a2d668cf Merge #9039: Various serialization simplifcations and optimizations
d59a518 Use fixed preallocation instead of costly GetSerializeSize (Pieter Wuille)
25a211a Add optimized CSizeComputer serializers (Pieter Wuille)
a2929a2 Make CSerAction's ForRead() constexpr (Pieter Wuille)
a603925 Avoid -Wshadow errors (Pieter Wuille)
5284721 Get rid of nType and nVersion (Pieter Wuille)
657e05a Make GetSerializeSize a wrapper on top of CSizeComputer (Pieter Wuille)
fad9b66 Make nType and nVersion private and sometimes const (Pieter Wuille)
c2c5d42 Make streams' read and write return void (Pieter Wuille)
50e8a9c Remove unused ReadVersion and WriteVersion (Pieter Wuille)
2018-01-15 06:14:15 +01:00
Wladimir J. van der Laan
8ed6722196 Merge #10250: Fix some empty vector references
f478d98 Fix some empty vector references (Pieter Wuille)

Tree-SHA512: a22022b9060cd39f8d349e8dd24490614c0028eae2fbc7186d0d26b1d47529049b2daee41f093c0722130274a0b6f7f8671c2295c8cb4a97028771eaff080734
2017-10-31 21:19:11 +01:00
Pieter Wuille
817ecc03d3 Merge #9353: Add data() method to CDataStream (and use it)
5113474 wallet: Use CDataStream.data() (Wladimir J. van der Laan)
e2300ff bench: Use CDataStream.data() (Wladimir J. van der Laan)
adff950 dbwrapper: Use new .data() method of CDataStream (Wladimir J. van der Laan)
a2141e4 streams: Remove special cases for ancient MSVC (Wladimir J. van der Laan)
af4c44c streams: Add data() method to CDataStream (Wladimir J. van der Laan)
2017-10-23 19:07:45 +02:00
Wladimir J. van der Laan
952383e16c Merge #7933: Fix OOM when deserializing UTXO entries with invalid length
1e44169 Add tests for CCoins deserialization (Pieter Wuille)
5d0434d Fix OOM bug: UTXO entries with invalid script length (Pieter Wuille)
4bf631e CDataStream::ignore Throw exception instead of assert on negative nSize. (Patrick Strateman)
4f87af6 Treat overly long scriptPubKeys as unspendable (Pieter Wuille)
f8e6fb1 Introduce constant for maximum CScript length (Pieter Wuille)
2017-10-19 10:51:50 +02:00
Oleg Girko
b621cfb5fb Backport Bitcoin PR#8708: net: have CConnman handle message sending (#1553)
* serialization: teach serializers variadics

Also add a variadic CDataStream ctor for ease-of-use.

* connman is in charge of pushing messages

The changes here are dense and subtle, but hopefully all is more explicit
than before.

- CConnman is now in charge of sending data rather than the nodes themselves.
  This is necessary because many decisions need to be made with all nodes in
  mind, and a model that requires the nodes calling up to their manager quickly
  turns to spaghetti.

- The per-node-serializer (ssSend) has been replaced with a (quasi-)const
  send-version. Since the send version for serialization can only change once
  per connection, we now explicitly tag messages with INIT_PROTO_VERSION if
  they are sent before the handshake. With this done, there's no need to lock
  for access to nSendVersion.

  Also, a new stream is used for each message, so there's no need to lock
  during the serialization process.

- This takes care of accounting for optimistic sends, so the
  nOptimisticBytesWritten hack can be removed.

- -dropmessagestest and -fuzzmessagestest have not been preserved, as I suspect
  they haven't been used in years.

* net: switch all callers to connman for pushing messages

Drop all of the old stuff.

* drop the optimistic write counter hack

This is now handled properly in realtime.

* net: remove now-unused ssSend and Fuzz

* net: construct CNodeStates in place

* net: handle version push in InitializeNode
2017-07-27 17:28:05 +03:00
MarcoFalke
333e1eaeea
Bump copyright headers to 2015
- Bump copyright headers to 2015
- [devtools] Rewrite fix-copyright-headers.py
- [devtools] Use git pretty-format for year parsing

Github-Pull: #7205
Rebased-From: fa6ad855e9 fa24439ff3 fa71669452
2016-01-05 14:13:33 +01:00
James O'Beirne
42cb388167 Add chainstate obfuscation to avoid spurious antivirus detection
Adds an `obfuscate` parameter to `CLevelDBWrapper` and makes use of it
for all new chainstate stores built via `CCoinsViewDB`. Also adds an
`Xor` method to `CDataStream`.

Thanks to @sipa @laanwj @pstratem @dexX7 @KyrosKrane @gmaxwell.
2015-10-06 07:46:10 -07:00
Cory Fields
d7d187e8a4 allocators: split allocators and pagelocker
Pagelocker is only needed for secure (usually wallet) operations, so don't make
the zero-after-free allocator depend on it.
2015-03-20 12:23:44 +01:00
Cory Fields
1630219d90 openssl: abstract out OPENSSL_cleanse
This makes it easier for us to replace it if desired, since it's now only in
one spot. Also, it avoids the openssl include from allocators.h, which
essentially forced openssl to be included from every compilation unit.
2015-02-15 11:34:02 -05:00
Pavel Janík
5262fde0ec Remove whitespaces before double colon in errors and logs 2015-01-31 17:38:28 -05:00
sandakersmann
f914f1a746
Added "Core" to copyright headers
Github-Pull: #5494
Rebased-From: 15de949bb9277e442302bdd8dee299a8d6deee60
2014-12-19 19:55:32 +01:00
Michael Ford
78253fcbad Remove references to X11 licence 2014-12-16 15:56:50 +08:00
Cory Fields
fa7361907a boost: split stream classes out of serialize.h
serialization now has no dependencies.
2014-10-22 15:21:06 -04:00