Compare commits

...

840 Commits

Author SHA1 Message Date
Nik Bougalis
6a55f99ede Set version to 0.29.0-hf1 2015-09-07 09:17:06 -07:00
JoelKatz
0b457497d0 Limit changed node count 2015-09-07 09:16:30 -07:00
Nik Bougalis
b7c9e33343 Limit the number of offers that can be consumed during crossing 2015-09-07 09:00:25 -07:00
Nik Bougalis
5964710f73 Set version to 0.29.0 2015-08-04 13:22:45 -07:00
Nik Bougalis
262a61564c Set feature activation date to Aug 17 2015-08-04 13:22:17 -07:00
Edward Hennis
4cc4421c82 Fix display discrepancy in fee. 2015-08-04 11:22:38 -07:00
JoelKatz
2786950c16 Fix ledger loading on startup 2015-08-04 11:05:02 -07:00
Vinnie Falco
b25f322c93 Set version to 0.29.0-rc6 2015-07-29 18:43:02 -07:00
JoelKatz
f77ecba896 Confirm valid suspend before relying on suspension 2015-07-29 18:42:14 -07:00
Nik Bougalis
2336fe2708 Set version to 0.29.0-rc5 2015-07-28 20:14:10 -07:00
Nik Bougalis
0cbd81146f Fix parsing in ledger_request 2015-07-28 20:07:53 -07:00
Miguel Portilla
a268c1a7ad Add uptime to crawl data (RIPD-997) 2015-07-28 20:07:53 -07:00
Nik Bougalis
3b7107b255 Set features activation to Aug 10 2015-07-28 20:07:53 -07:00
Tom Ritchford
a2ea89c64e Fix coroutine suspend 2015-07-28 20:07:19 -07:00
Tom Ritchford
b44cb1a64c Revert "Always use co-routines:"
This reverts commit 3d6e76046c.
2015-07-28 19:27:27 -07:00
Nik Bougalis
16c89aee04 Set version to 0.29.0-rc4 2015-07-23 12:32:43 -07:00
Nik Bougalis
abe735102a Fix metadata during apply:
Metadata is correctly generated for the case where a ledger entry is only changed as
a consequence of threading. This changes the result compared to previous versions,
which produced more than necessary for these cases.
2015-07-23 12:29:35 -07:00
David Schwartz
70a37811bd Set the fees in Ledger::setImmutable 2015-07-21 11:40:41 -07:00
Nik Bougalis
edab96e973 Set version to 0.29.0-rc3 2015-07-20 15:41:25 -07:00
Nik Bougalis
e7a50e2a5a Fix apply table metadata updates 2015-07-20 15:40:46 -07:00
Vinnie Falco
e18ba24670 Set version to 0.29.0-rc2 2015-07-17 13:31:08 -07:00
Vinnie Falco
f41fc87a33 Put OfferCreate bug fix on a ledger switch:
The fix for an off-by one bug that overstates the account reserve
during OfferCreate is set to become active on August 3rd. Before
this date, the program will exhibit the old behavior.
2015-07-17 13:25:03 -07:00
Vinnie Falco
5ec3534fea Set version to 0.29.0-rc1 2015-07-15 16:56:48 -07:00
Vinnie Falco
6bd39a316e Tidy up amendment feature macro 2015-07-15 16:56:45 -07:00
Yana
8434203e71 Add copyright notice 2015-07-15 16:56:44 -07:00
Nik Bougalis
59431c513a Add IOUAmount and XRPAmount (RIPD-976):
These numeric types replace the monolithic functionality
found in STAmount. They are not used yet.
2015-07-15 16:56:44 -07:00
Miguel Portilla
edc1bc35fd Add path find response field full_reply (RIPD-894) 2015-07-15 16:56:44 -07:00
Miguel Portilla
18ccdf8bd4 Add Directory container and iterator (RIPD-968) 2015-07-15 16:56:43 -07:00
seelabs
a0dcc4da8c Enable rm funded offer fix after a switch over date 2015-07-15 16:56:43 -07:00
seelabs
2b91e62d5d Fix funded offer removal during payment (RIPD-113):
In some cases, funded offers were incorrectly removed. This happened
when:

1) There are multiple payment paths.
2) A payment path has several offers in a row.
3) An offer causes a previous offer to become unfunded when calculating
   reverse liquidity and that offer does not satisfy the payment and
   there is another offer at the same quality.
4) The payment path is not used to satisfy the payment (there are other
   paths at better quality that do the job).
2015-07-15 16:56:43 -07:00
Vinnie Falco
bc5a25168a Update chrono types
Conflicts:
	src/ripple/test/jtx/impl/Env.cpp
2015-07-15 16:56:43 -07:00
Vinnie Falco
f453c58389 Fix manifest message handler 2015-07-15 16:56:42 -07:00
Vinnie Falco
ad74606ab3 Fix fees in Ledger construction
Conflicts:
	src/ripple/app/ledger/Ledger.cpp
	src/ripple/app/ledger/Ledger.h
	src/ripple/app/main/Application.cpp
	src/ripple/ledger/impl/View.cpp
	src/ripple/ledger/tests/View_test.cpp
	src/ripple/test/jtx/impl/Env.cpp
2015-07-15 16:56:42 -07:00
Vinnie Falco
bb15295935 Refactor computation of Ledger hash 2015-07-15 16:56:42 -07:00
Vinnie Falco
f0c1fbb098 Use LedgerInfo hash in applyHeldTransactions 2015-07-15 16:56:41 -07:00
Vinnie Falco
692f224e1c Tidy up genesis Ledger construction 2015-07-15 16:56:41 -07:00
Vinnie Falco
5bd9cd2ee8 Tidy up and move sources 2015-07-15 16:56:41 -07:00
Tom Ritchford
70fc091e74 Split up RPC handlers for classic build. 2015-07-15 16:56:40 -07:00
Tom Ritchford
1d09c54fdc Replace Ledger with ReadView in most RPC handlers. 2015-07-15 16:56:40 -07:00
Tom Ritchford
c7ebe7205c Move fields from Ledger to LedgerInfo. 2015-07-15 16:56:39 -07:00
Tom Ritchford
1b6c707abb Extract LedgerToJson.cpp from LedgerToJson.h. 2015-07-15 16:56:39 -07:00
Tom Ritchford
a0010effbc Simplify lookupLedger to use an RPC::Context. 2015-07-15 16:56:39 -07:00
Tom Ritchford
c094772bc0 Restrict Ledger.cpp to 80 columns. 2015-07-15 16:56:38 -07:00
Vinnie Falco
7ce871f3b2 Merge branch 'release' into develop
Conflicts:
	Builds/rpm/rippled.spec
	src/ripple/protocol/impl/BuildInfo.cpp
2015-07-15 16:56:10 -07:00
Nik Bougalis
77b3ad5de1 Set version to 0.29.0-b12 2015-07-13 16:38:40 -07:00
Tom Ritchford
a75a0c0b84 Mention rippled in the websocket test page. 2015-07-13 16:38:40 -07:00
Tom Ritchford
072fc53019 Rename duplicate .cpp files. 2015-07-13 16:38:39 -07:00
wilsonianb
5bad2db667 Add validations subscriptions (RIPD-504) 2015-07-13 16:38:39 -07:00
Miguel Portilla
7c2478480d DeliverMin enable switch and precheck greater than dest amount 2015-07-13 16:38:39 -07:00
Nik Bougalis
761f218c0a Refactor NetworkOPs:
* Reduce public API
* Use LedgerMaster interface from RPC
* Remove fetch pack management to LedgerMaster
2015-07-13 16:38:39 -07:00
Vinnie Falco
163e8eb8fc Use SecretKey, PublicKey 2015-07-13 16:37:04 -07:00
Vinnie Falco
6fccd07479 Add new cryptographic token types:
This replaces the equivalent functionality in RippleAddress.

* New PublicKey, SecretKey, Seed, Generator
* Removed AnyPublicKey, AnySecretKey
2015-07-13 16:37:04 -07:00
Vinnie Falco
c86a40a361 Tidy up digest functions:
* Add sha512_half_hasher
* Move sha512Half functions to digest.h
* Add explicit OpenSSL equivalents
2015-07-13 15:25:20 -07:00
Vinnie Falco
362726de4a Slice improvements:
* Rename to makeSlice
* Well defined default construction
* Add `empty`
* Add operator[]
* Buffer arithmetic
2015-07-13 15:25:20 -07:00
Vinnie Falco
5962a4817a Add secp256k1 module 2015-07-12 12:03:27 -07:00
Vinnie Falco
2e05471d72 Fix compilation with C++ 2015-07-12 12:03:27 -07:00
Vinnie Falco
d998c6461e Merge commit '94f13fb6061ead96fd5bc6ecd6ee5d9c5565a966' as 'src/secp256k1' 2015-07-12 12:03:20 -07:00
Vinnie Falco
94f13fb606 Squashed 'src/secp256k1/' content from commit 0cbc860
git-subtree-dir: src/secp256k1
git-subtree-split: 0cbc8600f3147c97ff0b404abebf5db19025b20b
2015-07-12 12:03:20 -07:00
Vinnie Falco
7edf783102 Set version to 0.29.0-b11 2015-07-12 11:51:27 -07:00
JoelKatz
efc2159441 Implement new amendment majority semantics :
This implements the tracking of when an amendment achieved a majority
in the ledger, ensuring that there's always network-wide agreement
on which amendments have achieved a majority and how long they've
held it.

* New fields
* Change transactor changes
* AmendmentTable API and implementation changes
* Update amendment enabled status on validated ledgers
* Reinstate support for ledger sequence in fee transactions
2015-07-12 11:51:27 -07:00
David Schwartz
3078c6da12 Check if synchronized in ripple_path_find
If a call to ripple_path_find does not specify a ledger,
the call should fail if the server is not synchronized
to the network.
2015-07-12 11:51:27 -07:00
Miguel Portilla
de6f678de7 Pass by reference in processTransaction 2015-07-12 11:51:26 -07:00
Nicholas Dudfield
d8d51e8103 Add quality to account_offers 2015-07-12 11:51:26 -07:00
Howard Hinnant
361f1da5b8 Optimize and clean up SHAMap::iterator:
* Remove dependence on boost::iterator_facade.
* Rename iterator to const_iterator.
* Change value_type from shared_ptr<SHAMapItem const> to SHAMapItem.
* Install a stack-path to the current SHAMapItem in the const_iterator.
2015-07-12 11:51:26 -07:00
Vinnie Falco
30e068ae17 Tidy up compilation units 2015-07-12 11:50:34 -07:00
Mark Travis
3b751cc6e6 Set version to 0.28.2-hf1 2015-07-09 22:57:16 +00:00
Miguel Portilla
6d60f19d73 Change NetOps processTransaction to use ref param 2015-07-09 22:56:03 +00:00
Vinnie Falco
94235d4b4f Set version to 0.29.0-b10 2015-07-09 14:21:49 -07:00
Vinnie Falco
367c3a5bfc Refactor View classes:
The View hierarchy of classes is reorganized to include new
classes with member functions moved and renamed, to solve
defects in the original design:

OpenView accumulates raw state and tx changes and
can be applied to the base. ApplyView accumulates changes
for a single transaction, including metadata, and can be
applied to an OpenView. The Sandbox allows changes with
the option to apply or throw them out. The PaymentSandbox
provides a sandbox with account credit deferral.

Call sites are changed to use the class appropriate for
the task.
2015-07-09 13:25:18 -07:00
Vinnie Falco
f3b172b0c9 Use OpenLedger in Env 2015-07-09 13:25:18 -07:00
Vinnie Falco
023715474c Add OpenLedger:
The OpenLedger class encapsulates the functionality of
maintaining the open ledger. It uses an OpenView with the
last closed ledger as its base. Routines are provided to
modify the open ledger to add new transactions, and to
accept a new last closed ledger. Business logic for
performing transaction retries is rewritten to fit this
framework and used in the implementation of accept.

When the RIPPLE_OPEN_LEDGER macro is set to 1 (BeastConfig.h),
the global Application OpenLedger singleton maintains
its open ledger in parallel by applying new transactions
and accepting new last closed ledgers. In the current
implementation this does not affect transaction processing
but logs any differences in the results as compared to
the original code.

Logging shows an occasional mismatch in what the OpenLedger
builds versus the original code, usually an OfferCreate
which gets a terINSUF_RESERVE instead of tesSUCCESS.
2015-07-09 13:20:28 -07:00
Vinnie Falco
f5873bcad0 Add unfunded account Env test 2015-07-07 12:55:56 -07:00
Vinnie Falco
9f27801b8d Log metadata differences on built ledger mismatch 2015-07-07 12:55:56 -07:00
Vinnie Falco
9eb0c2964c Pass a reference in SHAMap::compare 2015-07-07 12:22:50 -07:00
Vinnie Falco
73d64bbafc Set version to 0.29.0-b9 2015-07-07 10:14:31 -07:00
Tom Ritchford
ea67a2d051 Remove jss::account_index and jss::peer_index. 2015-07-07 10:14:31 -07:00
Vinnie Falco
1e7588d0ab Fix open ledger flag when jumping 2015-07-07 10:14:31 -07:00
Vinnie Falco
b6b3548c0c Remove redundant unit test 2015-07-07 10:14:27 -07:00
Vinnie Falco
097a8ce640 Merge branch 'release' into develop
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
	Builds/rpm/rippled.spec
	src/ripple/app/misc/NetworkOPs.cpp
	src/ripple/app/tx/impl/TransactionEngine.cpp
	src/ripple/protocol/impl/BuildInfo.cpp
	src/ripple/unity/app_tx.cpp
2015-07-07 09:35:41 -07:00
Vinnie Falco
6374aad9bc Set version to 0.28.2 2015-07-07 09:21:44 -07:00
Vinnie Falco
fed3f7b74b Set version to 0.29.0-b8 2015-07-02 15:53:05 -07:00
Vinnie Falco
c079d9ae38 Env_test fixes 2015-07-02 15:53:00 -07:00
Nik Bougalis
6a093b1b44 Fix SHAMapTreeNode deserialization 2015-07-02 15:50:11 -07:00
Miguel Portilla
4dc573f195 Add DeliverMin transaction field (RIPD-930) 2015-07-02 15:50:11 -07:00
Vinnie Falco
b7f07aed00 Add BasicView::txs memberspace interface 2015-07-02 15:09:10 -07:00
Vinnie Falco
cb791482a0 Serializer improvements:
* Add getSlice()
* Make getVLDataLength public
2015-07-02 15:09:10 -07:00
Vinnie Falco
bd7eb94d69 Refactor clock declarations in chrono.h 2015-07-02 15:09:09 -07:00
Vinnie Falco
223389a464 Tidy up abstract_clock:
* Add clock_type
* Make elapsed() const
2015-07-02 15:09:09 -07:00
Vinnie Falco
575f124fb8 Tidy up transactors:
* Rename some members
* Don't use SLE cached from the base view
2015-07-02 15:09:09 -07:00
Vinnie Falco
483f768370 Use BasicView:
Many functions and classes that used a Ledger now use a BasicView.

Calls to cachedRead are changed to call member read on the view,
note that this bypasses the SLECache optimization. To restore the
optimization, the BasicView passed at the top of call stacks
should be wrapped with a caching view, coming in future commits.
2015-07-02 15:09:08 -07:00
Vinnie Falco
ab20ca95aa Add hash to ViewInfo 2015-07-02 15:09:08 -07:00
Vinnie Falco
bf775036bc Add MetaView hold parameter 2015-07-02 15:09:08 -07:00
Vinnie Falco
08bfd302fe Apply tx to new open ledger on switch (RIPD-972):
When the last closed ledger jumps, transactions from the
old open ledger and local transactions need to be applied
to the new open ledger or else transactions could get lost
locally (but still relayed, and therefore make it into a ledger).

A harmful effect is that rippled will report that the transaction
was not applied even when it was, making robust transaction
submission malfunction.
2015-07-02 15:09:07 -07:00
Vinnie Falco
3b6ea02920 Fix missing tefEXCEPTION handling in apply 2015-07-02 15:09:07 -07:00
Howard Hinnant
26bfeb1319 Replace Serializer with Blob in SHAMapItem:
* This helps decouples SHAMap and Serializer.
* Restyle data member names.
* Rename getTag() to key().
2015-07-02 15:06:09 -07:00
Vinnie Falco
72659d431e Set version to 0.29.0-b7 2015-07-01 13:06:51 -07:00
Howard Hinnant
53dabe68ef Fix warning 2015-07-01 13:06:47 -07:00
Nik Bougalis
ccd6b46995 Fix shadowing 2015-07-01 12:34:00 -07:00
Vinnie Falco
91b3227a0f Fix canonicalization race in batch apply 2015-07-01 12:29:46 -07:00
Vinnie Falco
adebba94dc Set version to 0.28.2-rc3 2015-07-01 12:27:21 -07:00
Vinnie Falco
9d3b3f7a01 Fix canonicalization race in batch apply 2015-07-01 12:27:21 -07:00
seelabs
b354360bc0 Port DeferredCredits test to jtx and views 2015-07-01 13:45:56 -04:00
seelabs
8c24f7eb03 Account for deferred credits of parent views 2015-07-01 10:59:02 -04:00
Vinnie Falco
f473eade5a Set version to 0.29.0-b6 2015-06-30 19:52:28 -07:00
mDuo13
dc74a44b70 Update command-line usage message (RIPD-922) 2015-06-30 19:51:23 -07:00
Vinnie Falco
f96ac3db67 Refactor View, MetaView, and tx processing:
This tidies up the View interface and makes transaction
application a free function, with the removal of the
TransactionEngine class. A new class ApplyContext provides
all the state information needed to apply a Transactor. The
Transactor is refactored to perform all the processing
activities previously part of TransactionEngine.

The calculation of metadata from a MetaView is improved.
A new apply function performs all the steps for calculating
and inserting metadata into the tx map.

Transaction processing code path is passed a Config instead
of retrieving the global, and uses the Journal supplied in
the call to apply() consistently.

To support transaction processing and RPC operations, a
new POD type ViewInfo is added which consolidates static
information about open and closed ledgers, such as the ledger
sequence number or the closing times. Ledger and MetaView are
refactored to use this info.

The ViewInfo now contains the "open ledger" setting. The
tapOPEN_LEDGER ViewFlag is removed. The view property of
being an open ledger is obtained from the base or by using
the MetaView constructor which presents a closed ledger as
an open one.

View, MetaView:

* Fix missing includes
* Add apply free function
* Use Journal in TransactionEngine
* Use BasicView in TransactionEngine
* inline NetworkOPs::batchApply
* Add shallow_copy, open_ledger MetaView ctor tags
* Add ViewInfo with open flag, seq, close times
* Make parent_ a reference
* Tidy up ctor arguments and base_ name
* Remove tapOPEN_LEDGER
* add assert to MetaView::apply
* ViewInfo comment
* Throw, pass Journal in txInsert
* Add BasicView::txCount

TransactionEngine:

* Add apply
* Make TransactionEngine private
* Refactor MetaView::apply and apply()
* Rename to TxMeta
* Refactor treatment of metadata in MetaView, TransactionEngine
* Rename to ApplyContext
* Use ApplyContext& in Transactor
* Pass Config in ApplyContext
* Declare Transactor classes in headers
* Use view flags in Transactor
2015-06-30 19:26:02 -07:00
Vinnie Falco
b11b9939f4 Add contract interface 2015-06-30 12:29:58 -07:00
Vinnie Falco
e595fd5e02 Add JLOG macro 2015-06-30 12:29:57 -07:00
Vinnie Falco
af52276cd9 Set version to 0.29.0-b5 2015-06-30 11:33:45 -07:00
Vinnie Falco
2eec47415e Add enableTesting flag to applyTransactions 2015-06-30 11:33:45 -07:00
Vinnie Falco
4a2af70c2c Return tefEXCEPTION in TransactionEngine 2015-06-30 11:11:34 -07:00
Vinnie Falco
6211065802 Disable Websocket ping timer 2015-06-30 11:01:34 -07:00
Vinnie Falco
a338d9efe0 Return tefEXCEPTION in transaction engine 2015-06-30 10:59:39 -07:00
Vinnie Falco
e2ef423624 Disable Websocket ping timer 2015-06-30 10:56:48 -07:00
Nik Bougalis
0f8206e269 Set version to 0.29.0-b4 2015-06-29 17:19:52 -07:00
Nik Bougalis
4ccc3751d6 Remove unused function 2015-06-29 17:19:48 -07:00
Tom Ritchford
7ef6e58024 Tidy Json:
* Remove unused code.
  * Rename .inl file to .cpp.
  * Remove duplicate macros.
2015-06-29 17:11:17 -07:00
Vinnie Falco
57689c4e66 Refine View interfaces:
This shores up the View interface support for contextual
transaction processing by putting params in the View, and
provides support for replacing the open ledger with the
open MetaView.

Transaction metadata is now part of the View interface.
Stacked MetaViews correctly apply their transaction
metadata to the parent.

* Add lastCloseTime to View
* Add insertTx to View, implement in MetaView
* Add View::txExists for transaction checking
* Add Fees to View, cache fees in Ledger and MetaView
* Use ViewFlags in View
* Use tapENABLE_TESTING flag for features
* Use cached Fees in View
* Rename to ViewFlags
* Move FreezeHandling to View.h, remove ViewAPIBasics.h
* Remove BasicView::parent hack
* Remove calls to getLedger in Transactors
2015-06-29 17:06:48 -07:00
Nik Bougalis
2fc8d70655 Set version to 0.29.0-b3 2015-06-26 20:02:45 -07:00
Edward Hennis
7ee9f8513c Levelize RipplePathFind.h 2015-06-26 20:02:45 -07:00
Nik Bougalis
1a843fb4f6 Refactor consensus:
Classes implementing the consensus process on Ripple are cleaned
up in preparation for modularizations and compartmentalization.

Functions and state related to inter-round consensus are moved out
of NetworkOPs and into Consensus, where they are more effectively
isolated.

Some member functions are changed to free functions and some free
functions have their scope reduced to specific translation units.

* Track inter-round consensus state using new Consensus object
* Devirtualize interfaces
* Reduce NetworkOPs, Consensus and LedgerConsensus interfaces
* Add comments
2015-06-26 20:02:45 -07:00
Tom Ritchford
9111ad1a9d Handle empty Json values:
* Replace Json::Value::isNull() and Json::Value::empty with operator bool()
2015-06-26 20:01:02 -07:00
Tom Ritchford
a5a9242f4e Handle empty strings in Json::Value::empty() 2015-06-26 20:00:44 -07:00
Nik Bougalis
3fcf4ae8b7 Set version to 0.28.2-rc2 2015-06-25 14:46:43 -07:00
Nik Bougalis
c3d34aaf4d Fix shadowing 2015-06-25 14:45:32 -07:00
Vinnie Falco
e4f585b7fe Set version to 0.29.0-b2 2015-06-25 11:17:10 -07:00
Tom Ritchford
e3ac1001be Tidy up locks and locals. 2015-06-25 11:17:09 -07:00
Tom Ritchford
67f2a5d9d6 Remove duplicate and shadow variables. 2015-06-25 11:17:09 -07:00
Edward Hennis
89b9fa0b35 Fix shadowing 2015-06-25 10:57:03 -07:00
JoelKatz
4c0de726c8 Require longer delays before disconnecting peers 2015-06-25 10:55:59 -07:00
JoelKatz
7d96075e14 Avoid lock overlap:
Prefer to release the InboundLedgers lock before acquiring
a lock on a specific ledger
2015-06-25 10:55:40 -07:00
JoelKatz
924a8cdd4b Rework of InboundLedgers::mRecentFailures:
This provides more precise tracking of failed ledger acquires
and more useful information in fetch_info.
2015-06-25 10:55:36 -07:00
Miguel Portilla
b27d078c67 Path finding unit tests (RIPD-731)
Conflicts:
	src/ripple/app/paths/tests/Path_test.cpp
	src/ripple/unity/app_paths.cpp
2015-06-25 10:54:45 -07:00
JoelKatz
c64ec9cfb9 Use continuation in legacy pathfinding:
Handle legacy (ripple_path_find) requests that don't specify a ledger
the same way regular path_find requests are. This provides a
performance improvement for these requests and reduces the problem
of server busy errors.

Conflicts:
	src/ripple/app/paths/PathRequest.cpp
2015-06-25 10:32:04 -07:00
JoelKatz
3d6e76046c Always use co-routines:
This permits RPC handlers to suspend and reschedule:
2015-06-25 10:30:06 -07:00
Vinnie Falco
48d6a4ab6a Refactor MetaView (RIPD-954):
Obsolete functionality is removed. DeferredCredits is moved
to a new class PaymentView, and used in RippleCalc.
2015-06-25 10:27:15 -07:00
JoelKatz
f535304e1b Use new MetaView functionality in RippleCalc (RIPD-954):
RippleCalc is changed to stack views when calculating results
instead of making a copy of the MetaView, improving efficiency.
2015-06-25 10:23:36 -07:00
Vinnie Falco
2f485672fa Refactor AccountID (RIPD-953):
All AccountID functionality is removed from RippleAddress and
replaced with free functions. The AccountID to string conversion
cache is factored out as an explicit type with an instance in
the Application object. New base58 conversion functions are used,
with no dependence on OpenSSL.

All types and free functions related to AccountID are consolidated
into one header file. Routines to operate on "tokens" are also
introduced and consolidated into a single header file.

A token one of the cryptographic primitives used in Ripple:

    Secret Seed
    Server Public Key
    Server Secret Key
    Account ID
    Account Public Key
    Account Private Key

    and these deprecated primitives:

    Account Family Seed
    Account Family Generator
2015-06-25 09:05:06 -07:00
Vinnie Falco
63d438c979 Add digest.h and protocol digest classes 2015-06-24 16:28:36 -07:00
Vinnie Falco
c955c03197 Add SHA256 and RIPEMD-160:
* Renamed files to reflect digest family names
* Add SHA256 to SHA2
* Add RIPEMD-160 to RIPEMD
* Reduce duplicated code
2015-06-24 16:28:35 -07:00
Vinnie Falco
ceff6bc271 Set version to 0.29.0-b1 2015-06-22 19:32:26 -07:00
seelabs
80a5f5878f Add offer jtx test 2015-06-22 19:32:26 -07:00
Howard Hinnant
1e6111c09c Make the data of a SHAMap const:
* Hold a shared_ptr<SHAMapItem const> instead of a shared_ptr<SHAMapItem>.
* Compiler helps us enforce data immutability.
* Make SHAMapAbstractNode::addRaw const

Conflicts:
	src/ripple/app/ledger/Ledger.cpp
	src/ripple/app/ledger/Ledger.h
	src/ripple/app/ledger/LedgerHistory.cpp
	src/ripple/app/ledger/LedgerToJson.h
2015-06-22 18:39:33 -07:00
Vinnie Falco
d468deee12 Refactor Ledger and LedgerEntrySet:
Member functions and free functions on Ledger and LedgerEntrySet are
rewritten in terms of new abstract interfaces `BasicView` and `View`,
representing the set of non-decomposable primitives necessary to read
and write state map items in a ledger, and to overlay a discardable
view onto a Ledger that can calculate metadata during transaction
processing. const-correctness is enforced through the parameter and
return types.

The MetaView now supports multi-level stacking: A MetaView can be
stacked on top of either a Ledger or another MetaView, up to any
number of levels.

The getSLEi member function is removed. The CachedView wrapper
replaces it, wrapping a View such that any function called with a
CachedView will go through the SLECache.

* Add BasicView, View, CachedView
* Rename LedgerEntrySet to MetaView
* Factor out free functions
* Consolidate free functions in ViewAPI
* Remove unused class members and free functions
2015-06-22 18:39:33 -07:00
Vinnie Falco
e7eb3aa63d Set version to 0.28.2-rc1 2015-06-19 16:03:42 -07:00
JoelKatz
749f31f69d Tidy up SHAMap node handling of invalid wire formats 2015-06-19 16:03:42 -07:00
Vinnie Falco
2d6af1da1d Add SigningPubKey regression test 2015-06-19 16:03:42 -07:00
JoelKatz
6ec5fa9cae Fix null pointer in ec wrapper 2015-06-19 15:53:41 -07:00
JoelKatz
72832c0fa2 More robust call to get the valid ledger index 2015-06-19 15:53:32 -07:00
Vinnie Falco
7d329570f4 Set version to 0.28.2-b10 2015-06-18 15:35:48 -07:00
Edward Hennis
c334093223 jtx: Add ledger advance.
Conflicts:
	src/ripple/test/jtx/impl/Env_test.cpp
2015-06-18 15:35:46 -07:00
Edward Hennis
27274c9620 jtx: Add JTx properties. 2015-06-18 15:34:41 -07:00
Vinnie Falco
cd5e36045c jtx: json, memo funclets, fixes, improvements:
* Add json funclet
* Add memo funclet
* Add Env::trace
* Add PrettAmount regression test
* Fix PrettyAmount construction
* Make Env::trust balance-neutral
* Log parse errors during signing
2015-06-18 15:33:44 -07:00
Tom Ritchford
0062a260b9 Fix warning 2015-06-18 13:56:15 -07:00
Nik Bougalis
fdd2ea8feb Set version to 0.28.2-b9 2015-06-15 19:43:03 -07:00
Tom Ritchford
fbc1768784 Fix JobQueue synchronization. 2015-06-15 19:43:03 -07:00
Vinnie Falco
c53b9f3713 Add SHAMap::iterator 2015-06-15 19:43:03 -07:00
Vinnie Falco
eb709f415b Tidy up jtx:
* Tidy declaration order
* Remove AccountInfo
* Remove Env autofill settings
2015-06-15 19:43:02 -07:00
Vinnie Falco
9dd08e4dab Rename Account to AccountID 2015-06-15 19:43:02 -07:00
Tom Ritchford
e1cd1e9e32 Add header 2015-06-15 19:43:02 -07:00
Howard Hinnant
f875603525 Split SHAMapTreeNode into leaf and inner nodes.
* This reduces the memory requirements of both leaf and inner nodes.
* The name SHAMapTreeNode is retained for leaf nodes so as to keep
  the public API of SHAMap stable.
2015-06-15 19:43:02 -07:00
JoelKatz
e95ab65396 Improve peer send queue management:
* Disconnect peers on sustained large send queues
* Disconnect peers on sustained failure to pong
* Refuse some queries if send queue is at target
* Allow latency to exceed ping timer interval
2015-06-15 19:43:02 -07:00
JoelKatz
e0907ede4f GatewayBalances RPC command
RPC command to get a gateway's hot wallet balances
and total obligations.
2015-06-15 19:43:02 -07:00
Vinnie Falco
17020ffc54 Fix MSVC link 2015-06-15 19:43:02 -07:00
Nik Bougalis
abd05a6378 Set version to 0.28.2-b8 2015-06-13 21:02:51 -07:00
Vinnie Falco
189592938a Improvements to jtx framework:
This adds "require" functionality which allows invariants
to be checked after processing transactions using a simple,
terse interface. Also adds more comprehensive test coverage
for the framework itself, verifying that the more sophisticated
language constructs work in all ways.

All functions and classes have been split up into individual
files which may be included a-la carte, or accessed through
a single convenience header <ripple/test/jtx.h>

* Move, rename all sources
* Put everything in the jtx namespace
* Add sendmax funclet
* Rename funclet to paths
* Correctly set input issue and destination amount in path
* Conditionally invoke funclets using is_call_possible
* Add any() function means "any currency they will accept"
* Add None, none modifiers on amounts to mean "no amount"
* Add require conditions to JTx
* Add Env::require variadic condition checker
* Add le, rename some items for consistency
* Add require functors, balance, flags, nflags
* Add require functors lines, owners, offers, tickets
* Add ticket example of extending the system
* Add noripple modifier for funding accounst
* Add Env::st to parse Json into STTx
* Add tests to ensure correctness of fund()
* Add virtual Env member hooks
* Add Env::balance
* Add Env::seq
* Add PrettyAmount
* Add all container Account support
* IOU and XRP return PrettyAmount amounts
* IOUs print the issuer's name instead of base58
* Fix int and double conversions to XRP
* Fix autofill of Env::fund with noripple
2015-06-13 21:02:51 -07:00
Vinnie Falco
4f34724c5a Conditionally enable tickets at run time 2015-06-13 21:02:51 -07:00
Vinnie Falco
e958f72ba9 Convert to bool in suite::expect 2015-06-13 21:02:51 -07:00
Vinnie Falco
5c5b121b62 Add is_call_possible 2015-06-13 21:02:50 -07:00
Vinnie Falco
d21171b21e Refactor LedgerEntrySet:
* Remove duplicate:
    This changes behavior to fix an apparent bug. The
    copy will now correctly inherit mParams instead
    of reverting to tapNONE

* Tidy up LedgerEntrySet declarations
* Tidy up TransactionEngine
* Tidy PathCursor declarations
* Add LedgerEntrySet::apply
* Add LedgerEntrySet ctor
* Add Keylet, keylet namespace
* Add defaulted copy members
* Use optional in TransactionEngine
* Use optional<LedgerEntrySet> in PathState
* Return shared_ptr in Ledger::fetch
* Don't call entryCache with zero
* Deprecate invalidate
* Remove default constructor
* Remove unused container API
* Remove CountedObject base class
* Remove insert, clear
* Remove entryCreate overload
* Remove unused and tidy up STLedgerEntry
* Make getEntry private and tidy
* Replace members with adjustOwnerCount free function
* Replace accountFunds with funds free function
2015-06-13 21:02:50 -07:00
MarkusTeufelberger
aead038215 Fix docs 2015-06-13 12:02:28 -07:00
Nik Bougalis
a16c07c78a Remove unused NodeIdentity table fields 2015-06-13 12:02:22 -07:00
Nik Bougalis
3aebabce3d Revert "Enable EDH only for anonymous SSL contexts":
The issue was caused by client-side functionality added to IE
to protect against LOGJAM. By properly supporting larger keys
we no longer need to disable Ephemeral DH.

This reverts commit 3028ffd083.
2015-06-13 11:55:03 -07:00
JoelKatz
7239bcf0b7 Support larger EDH keys:
In the past we used only 512-bit EDH keys. To protect against the
LOGJAM attack, OpenSSL 1.0.1n and later versions reject EDH keys
that are less than 768 bits and a future version will increase the
minimum to 1024.

We now have DH parameters for 1024-bit and 2048-bit EDH keys and
will correctly return and use those, when asked. Note that at this
time, OpenSSL will only ask for 512 or 1024 bit keys.
2015-06-13 11:55:03 -07:00
Tom Ritchford
623faa1550 Fix warning 2015-06-13 11:55:03 -07:00
Nik Bougalis
60fad25476 Beast clean up:
* Remove binding, dispatch handling and exit hooks in favor
  of std alternatives; remove crash-handling infrastructure,
  error message framework, system-specific process handling
  and Objective-C interop helpers.
* Simplify Beast function profiling
* Simplify beast::Time interface
* Simplify beast::String interface
* Simplify beast::File interface
2015-06-13 11:55:03 -07:00
Tom Ritchford
d06e07ef0e Correctly compare JSON values. 2015-06-13 11:55:03 -07:00
Mark Travis
ca800f9e8d Batched transaction application:
Applying multiple transactions to the open ledger
reduces SHAMap modification overhead.
2015-06-13 11:53:45 -07:00
Nik Bougalis
4225b78bf5 Set version to 0.28.2-b7 2015-06-10 16:02:29 -07:00
Nik Bougalis
8c68eff460 Cleanup object templates:
* Avoid exposing class members - use boost::iterator_range instead
* Use std::make_unique instead of naked new
2015-06-10 15:59:52 -07:00
Tom Ritchford
c2814308f1 Remove unused parameters to accountFromString. 2015-06-10 15:56:24 -07:00
Nik Bougalis
f237187b0d Remove cache sweep profiling 2015-06-10 15:55:05 -07:00
Nik Bougalis
187b4caf3c Add logging support to Taker:
Log progress during offer crossing and flow calculations to
allow for easier debugging and transaction analysis. All
logging is done at debug and trace level and will normally
not be visible.
2015-06-10 15:54:27 -07:00
Tom Ritchford
b8526f7894 Allow RPC yield to be a continuation. 2015-06-10 15:54:07 -07:00
Tom Ritchford
b2b0377717 New method JobQueue::getJobForThread().
* Clean up mutability.
* Add override specifiers.
* Get rid of unused parameters.
2015-06-10 15:53:59 -07:00
Nik Bougalis
24ea1ab035 Parse pathsets when accounts are specified in hex 2015-06-10 15:53:04 -07:00
Nik Bougalis
e980e69eca Acquire logic fixes:
In InboundLedgers::acquire, properly return a ledger if we are
able to create one immediately.

In LedgerMaster::walkHashBySeq, don't walk the whole ledger if
we already know we have it.
2015-06-10 15:52:48 -07:00
Vinnie Falco
2904add428 Set version to 0.28.2-b6 2015-06-08 17:25:17 -07:00
Vinnie Falco
babaac9305 Refactor Ledger and support classes:
This performs a deep refactor on the Ledger class and its supporting
classes, in preparation for the move to shared_ptr<SLE const> in
places where the SLE is immutable and we are currently using
shared_ptr<SLE>.

Member functions are converted to free functions, the SLECache is an
explicit parameter, one line convenience functions are removed to
streamline the interface. Some callers are changed to use <SLE const>
instead of <SLE>

SLECache:
* Moved to its own header file

RippleState:
* Remove unused functions
* Store the SLE as const
* Simplify callers

AccountState:
* Remove unused members
* Simplify existing members

Ledger:
* Replace writeBack with insert and update
* Remove unused functions
* Remove LedgerStateParams
* Move getLastFullLedger to Application
* add entryCacheI, exists, fetch, erase
* Use boost::optional where it makes sense
* Make member functions free functions

Free functions:
* fetch: cache-aware SLE retrieval
* forEachItem, forEachItemAfter
* (various)
2015-06-08 17:25:16 -07:00
Vinnie Falco
454d2f8c45 Add SHAMap::fetch returning SHAMapItem const 2015-06-08 15:38:19 -07:00
Howard Hinnant
5d42d52660 C++14 readiness 2015-06-08 15:38:19 -07:00
Edward Hennis
a0e87c7aee ConnectedAddresses stores Addresses to avoid port issues.
* Also change log level on a couple of Overlay messages.
2015-06-08 15:07:06 -07:00
Edward Hennis
49c4ec6f93 Travis build unity and nounity. 2015-06-08 15:06:28 -07:00
Nik Bougalis
eb0ece417d Fix move sequencing 2015-06-08 15:05:33 -07:00
seelabs
7b5bf7f129 Add support for scons ninja backend 2015-06-08 15:05:20 -07:00
Vinnie Falco
ab8ffc1a00 Set version to 0.28.2-b5 2015-06-02 18:00:31 -07:00
Vinnie Falco
64c8335e22 New Env transaction testing framework:
This adds a suite of tools used to write unit tests. The Env provides
a context containing a ledger, and routines that assemble transactions
from JSON with optional "funclets" that add details in an exensible, terse
notation.
2015-06-02 18:00:31 -07:00
Vinnie Falco
4cfffdf76f Add pretty(Json::Value) 2015-06-02 16:52:23 -07:00
Vinnie Falco
8adc4c1e3c Add rpcErrorString function 2015-06-02 16:52:22 -07:00
Vinnie Falco
02c118981f Add jss fields 2015-06-02 16:52:22 -07:00
Vinnie Falco
4825cefbf8 Add strHex(Slice) 2015-06-02 16:52:22 -07:00
Vinnie Falco
4b91a18532 Remove linefeed from JSON to string conversion 2015-06-02 16:52:21 -07:00
Vinnie Falco
ff2453e42c Add missing include 2015-06-02 12:55:25 -07:00
Vinnie Falco
269ad321e6 Allow multi-sign to be enabled at runtime:
This lets unit tests exercise multi-sign interfaces
without having to set RIPPLE_MULTI_SIGN_ENABLE.
2015-06-02 12:55:25 -07:00
Vinnie Falco
8be4e7e65f Refactor Serializer, SerialIter, SHAMapItem, NodeObject:
* Make LessThan private
* Make NodeObject::isSame private
* Remove hotTRANSACTION
* Remove some Serializer members
* Remove unused SHAMapItem::getRaw
* Remove unused STLedgerEntry::getOwners
* Remove Serializer constructors
* Remove unused Serializer members
* Remove SerialIter ctor
2015-06-02 12:55:07 -07:00
Vinnie Falco
c25184cc88 Add sha512Half and SHA512HashHasher:
These routines replace existing code to compute SHA512-Half hashes.
The new code accumulates serialized data into a hashing context
instead of allocating a buffer, for improved performance.
2015-06-02 12:52:10 -07:00
Vinnie Falco
06823349f9 Tidy up Serializer:
* Remove getSHA512Half size parameter
* Remove unused Serializer::getSHA256
* Remove Serializer::getRIPEMD160
2015-06-02 12:49:30 -07:00
Vinnie Falco
e18c6f63cc Add SHA512 hasher:
* Remove unused SHA256
2015-06-02 12:49:30 -07:00
Vinnie Falco
36a864106d Update hash_append to latest draft specification 2015-06-02 12:49:30 -07:00
JoelKatz
3028ffd083 Enable EDH only for anonymous SSL contexts
Enabling EDH breaks compatibility with some versions of IE. Disabling
EDH is an acceptable workaround.
2015-06-02 12:49:11 -07:00
Nik Bougalis
a3d5a97df6 Remove unused old-style unity files 2015-06-02 12:48:44 -07:00
Mark Travis
52879d964e Revert "Reduce SHAMapTreeNode copying during SHAMap unsharing:"
This reverts commit 47c6ab0ced.
2015-06-02 12:48:30 -07:00
Vinnie Falco
aaf209485c Merge remote-tracking branch 'david/lz4' into develop 2015-06-02 12:47:51 -07:00
Scott Schurr
4515ac0bca Replace base_uint(string) with from_hex_text<> (RIPD-897)
Removes the base_uint constructor that took a string.  Replaces
that functionality with two free functions named from_hex_text<>.
Use of from_hex_text<> looks like this:

auto v = from_hex_text<uint256>("AAA555");
static_assert (std::is_same<decltype(v), uint256>::value, "Huh!");

from_hex_text<> only operates on base_uint types.  At the moment the
list of those types include:

 o uint128,
 o uint160,
 o uint256,
 o Directory,
 o Account,
 o Currency, and
 o NodeID.

Using from_hex_text<> with any other types will not compile due to
an enable_if.
2015-06-02 12:46:03 -07:00
seelabs
d7def5509d Remove temp_db (RIPD-887) 2015-06-02 12:45:29 -07:00
JoelKatz
4ff845ac91 Merge commit 'df26c08a34b4e07235d33fcd7e2fb311d83f069f' into HEAD
Synchronize LZ4 with upstream
2015-05-29 15:03:27 -07:00
JoelKatz
df26c08a34 Squashed 'src/lz4/' changes from e25b51d..baf78e7
baf78e7 Merge pull request #111 from Cyan4973/dev
6f50184 Updated NEWS
acae59a Fixed : default sparse mode disabled on stdout, to support ` >>`  redirection scenario reported by Takayuki Matsuoka (#110)
91c1b9a Performance fix : big compression speed boost for clang (+30%)
0fb0392 Merge branch 'dev' of github.com:Cyan4973/lz4 into dev
bb22103 Merge pull request #107 from t-mat/issue/103pr2
7d72c0c Added LZF
e769a0e Combine unique .lz4 file info
ffff9ee Support iterative edit and testing
a8fdeb4 Add log output of succeeded decompression to test script
5151c30 Add log of same files and sha1 hash of unique files to versionstest
26065c3 Fixed  : LZ4IO exits too early when frame crc not present, reported by Yongwoon Cho (#106)
87e560e minor tests improvements
a9ff13a minor test refactor
58b5aad Fixed sparse issue with non seekable streams (#105)
60d657a removed "flush" argument to please Travis's python version
cdb136d cosmetic changes, 2nd try
c779c80 minor cosmetic changes for Takayuki's testVersions
26021db Merge branch 'dev' of github.com:Cyan4973/lz4 into dev
e3b5bf3 Merge pull request #104 from t-mat/issue/103pr2
fe11e0b Issue #103 : Add compatibility test between releases
f02c467 Added a few more interoperability tests (32bits vs 64 bits)
05c3f66 Updated a few comments
9607848 Fixed minor typo
45e1995 minor introduction update
7d182b8 Merge pull request #102 from Cyan4973/dev
fdd0029 minor parsing update
672bfde Updated comments
b4ef93a Fixed typo
efbebd2 Added : LZ4_compress_destSize()
1c3e633 Added compilation flag -Wcast-qual
05b0aa6 Updated readme
e05088d Updated lz4hc API
b4348a4 Fixed minor Visual warning
1171303 Updated streaming examples
1b17bf2 New lz4 API, using LZ4_compress_fast()
b495c91 Merge pull request #99 from eberge/dev
791512c Fixed bug 9318
2a974d7 refactored lz4hc
1e751a7 Install the lz4frame.h header in the cmake build
ad2dd6d moved lz4frame context types to incomplete typedef
c9cbb8f Increased aligment requirement for lz4frame context pointer
ef55dfb Modified lz4frame context typedef, to enforce stricter alignment condition
87a1c70 Fixed minor static analyzer warning
d6dc0a4 streaming API : Improved ring buffer management
bda38fd Merge pull request #98 from eberge/dev
a9a24e8 cmake support for AIX, HPUX, Solaris and Windows
9c6fb8b Added LZ4_compress_fast_extState()
b05d3d7 Frame content size disabled by default when using LZ4F_compressFrame(), to be in better coherence with the advanced API LZ4F_compress_update()
b805d58 Removed obsolete functions from lz4 cli
f11afaf Removed LZ4_compress() (obsolete) from lz4
72e6794 Updated LZ4F_freeDecompressionContext(), to provide stage hint as result
a01e10d Changed LZ4F compressionLevel from unsigned to signed, in anticipation for LZ4_compress_fast() integration.
cbcdd88 Fixed frame concatenation
e18aa90 Fixed frametest
c035b7a Restored make-lz4
197982e Fixed unfinished frame (issue #75)
409f816 Updated LZ4F_getFrameInfo() behavior, related to uncomplete frame header decoding attempts
47c3040 added --no-sparse test
9fd4f1f Sparse file support is now enabled by default
7644bee test error message in multiple files mode
bce2eeb Reclassified some notification messages as errors
9e92bee stronger arm tests
2ed9dcc fix minor "divide by zero" risk
633c1ca fixed minor leak
0ed2e71 Static analyzer generates error codes on bug suspicion
2cf8a19 minor header refactoring
634e4ee Merge pull request #96 from t-mat/improve-pr-95
e328d41 minor optimization for small files
13c6e16 Removed status notification in multiple-files mode
d153aaa Add LZ4F_OBSOLETE_ENUM() to describe obsolete enums
a430b85 Multiple files decompression refactoring
4e574e7 Updated lz4frame error names
d37926b Merge pull request #95 from t-mat/issue/90
240b554 Merge pull request #94 from t-mat/dev
3d46d4b Fix LZ4_DEPRECATED() in lz4hc.h
5f732e1 Merge pull request #91 from t-mat/dev
175890f Issue#90 : Change old enum names to new one
585bab8 Issue#90 : Change old enum to macro to maximize compatibility
081bcca Issue#90 : Add LZ4F_ prefix
e1283c7 Fix LZ4_DEPRECATED() for older/non-gcc/clang/MSVC compilers
d7298d2 Replace GCC_VERSION with LZ4_GCC_VERSION
9851583 Merge pull request #93 from drcrallen/descriptiveFrameErrors
b664a72 Revert "Revert "Add more descriptive frame errors""
3f4f623 Valgrind tests generate errors
83e350d Merge branch 'dev' of github.com:Cyan4973/lz4 into dev
066e9d3 Merge pull request #92 from Cyan4973/revert-89-descriptiveFrameErrors
5a66527 Revert "Add more descriptive frame errors"
0dc8308 Merge pull request #89 from drcrallen/descriptiveFrameErrors
05a46fc Changes LZ4F_compressBound() definition using NULL prefsPtr to cover worst case instead of default.
348f509 lz4io refactoring
eabc6d8 New valgrind test with multiple files
113b150 Fix leak issue with compression of multiple files
c64200d Improved performance when compressing a lot of small files
cc24124 minor compatibility fixes
ccba7a0 Merge pull request #86 from KyleJHarper/origin/r129/multiple_inputs_patch
d535214 Add more descriptive frame errors
bc28fc1 Merge pull request #87 from t-mat/fix-example2
fd77bad Replace obsolete functions
b036eaa Add snprintf macro for MSVC
7f2f1fc Added support for continuation of file compression and decompression if input files are missing.  Should more closely match gzip/bzip2/xz and so forth.  Also removed a debug print accidentally left in.
0169502 Added new LZ4IO_decompressMultipleFilenames to allow decompression of multiple files with the -m switch added in r128 (ref: google code issue 151).  Limitation: will only process files matching LZ4_EXTENSION macro, which for now seems reasonable.
da11725 new memory leak test for fullbench using multi-files
2c79887 Shortened tests durations
42e5bc4 Updated badges
2852b9e Fixed issue #84
8f49666 Fixed : minor coverity warning
8a61000 Fixed a few coverity warnings
138673d fixed minor g++ warning
cc8d617 Merge pull request #82 from t-mat/add-lz4-prefix
81fdd9d Fixed a few Valgrind warnings
ad86910 Add LZ4 prefix to deprecation macros
66b8a4a Fixed : minor Visual warnings
62ed153 Fixed : a few minor coverity warnings
9443f3d Extended obsolete warning messages to lz4hc
973e385 Implemented obsolete warning message
be9d248 Update lz4hc API : LZ4_compressHC_safe()
a07db74 Clarified lz4frame.h inline doc
8b8e5ef fixed minor sanitize warning
c22a0e1 Updated : fuzzer tests can be programmed for a timelength
a2864fd Fixed a few minor sanitize warnings
33134fb Added : sanitize test
f344fbd Fixed a few warnings from -fsanitize=undefined
2f8a4c3 New LZ4_compress_safe() API
1853622 fixed over-cautious visual warning
b41137f minor Makefile test refactoring
327cb04 minor memory leak fix and test
43e0535 fix g++ typecast
61d7416 updated doc
17f8614 added : memtest on fullbench
d38b0b6 Merge pull request #73 from funcodeio/dev
979a991 memcpy speed as reference
157a739 Merge pull request #74 from Cyan4973/fastMode
dd69902 Removed unused lines.
43eaf8f Merge pull request #72 from fzort/master
f72761f new tests for large files with content size support (#70)
90c0104 Added : progress indicator, in fast and decompression modes
1d3ab5d Cygwin has fileno, so there's no need to use _fileno.
78d2dfd fullbench : tests of _limitedOutput variants intentionnally provides less memory space than safe (LZ4_compressBound())
ef7cd83 Fixed issue 160, reported by Eric Berge
28e237e simplified LZ4_compress_limitedOutput()
89eee0d Removed make dist
0615eb4 Stricter tests : treat warnings as errors
76a03c1 simplified LZ4_compress_withState()
6625068 simplified LZ4_compress()
886b199 Modified files rights
7b5e945 Removed Visual 2013 solution, as AppVeyor automated mode only works with a single solution
117ab8c Added : Visual 2013 solution
08b24af Updated Visual 2012 solution : + 3 projects (fullbench, frametest, datagen)
a761546 Fix : minor warning under Visual
bf146ec Removed .suo & .user files from Visual solutions
7db6678 Restored proper credit
3bba55c Fixed : Windows compilation Added : Appveyor badge
160661c Merge pull request #69 from Cyan4973/dev
8437a0e Fixed : Visual compilation
7c26b03 Updated make dist
f174964 Added : Frame documentation in MarkDown format
880381c Removed HTML Frame Format documentation
5b9fb69 minor tweak
4783cb8 Updated readme
4c227a4 Added LZ4_compress_fast()
003af71 Merge pull request #67 from Cyan4973/dev
2a82619 fixed fullbench memory allocation error
6c69dc1 faster compression in 64 bits mode
44793b8 Updated documentation
b93f629 changed file name
eeb8bea Updated comments on LZ4F_getFrameInfo()
002ec60 restored lz4hc compression ratio
987e78c Merge pull request #66 from Cyan4973/dev
8cb06d5 lz4frame validates contentSize during decompression
d5da787 Changed struct member to contentSize
2d4fed5 Merge pull request #65 from Cyan4973/dev
ce71b07 converted to markdown friendly syntax
1ba37f3 Reference format doc
5780864 Fixed : Makefile
b009767 windows friendly make clean
27f7d06 minor beautifier (make clean)
b4755c7 Added : arm cross-compilation test
a357f43 Fixed cast-align warnings on 32-bits
4a9335b Added : doc authorship
e652285 Merge pull request #63 from t-mat/comment-on-example-directory
2af52a9 Add "Examples" subtree
679afea Add README.md as table of contents
19665c9 Add document for "Line by Line Text Compression" example
438fee9 Add document for "Double Buffer" example
a38166b Add document : "Streaming API Basics"
80e71c6 Updated man page : "--[no-]X"
5950f72 Updated tests
6b923d5 Updated long commands, with reverse "--no-" variants
d0f8d40 updated dist list
00c3208 Merge pull request #61 from Cyan4973/dev
7f436a1 lz4 cli supports frame content size
a28b147 removed useless man pages
7cf4e5c Updates tests & Man pages
f02adc7 new long commands
86715b2 Some more tests related to frame content size
7ee7256 frame content size support
7d87d43 Updated lz4io sparse file support (alignment properties)
b54d256 minor lz4frame optimisation (no more malloc() on using LZ4F_compressFrame() in fast mode)
da9402c minor lz4frame refactoring
859fe3b Updated LZ4 frame format documentation
8edb7f1 Added : Readme into lib directory, to explain what does each file
e7fb4d1 lz4 utility supports "pass-through" mode
2a02455 minor refactoring
3a68324 skippable frames support
93849d1 minor CMakeLists update
471eabe Merge pull request #60 from Cyberunner23/master
ef029a1 Removed checking of CMAKE_SYSTEM_PROCESSOR when adding -fPIC, breaks when that var is '64bit'.
c9a2b14 removed -s command from lz4c specific list of legacy commands
207aafd Added :  unlz4 symbolic link to "lz4 -d"
2b55752 changed "make install" default install directory to /usr/local
bbcfe21 Added : clang test
8a87769 Fix : static analyzer test on Travis
45b0642 scan-build tests
a18fb43 Merge pull request #58 from Cyan4973/sparseFile
248b761 windows sparse file support
d11ac40 Improved sparse files support
45a357f Improved sparse file support
e38c268 Fixed minor g++ warnings
12ab415 Preliminary support for sparse files
e3f33d2 Fixed minor warnings
74a6b14 Merge pull request #57 from alexDarcy/master
f2cc4be Updated Cmake configuration for non-gnu compiler
ceec6fa g++ compatibility
6b0c39b Updated datagen (can create sparse files)
e277511 Merge pull request #54 from t-mat/gc-issue/155
e1d9b59 Fixed : static library (x64 binary)
32a85fc NetBSD compatibility (#48)
488029e Updated : compress multiple files
046bd3a Merge pull request #52 from KyleJHarper/r128/multiple_inputs
dcdd628 Fix sentinel bit pattern
de5c930 Fix sentinel size miscalculation
eed7952 Add GNU coreutil's is_nul() method to isSparse()
b372f45 Add Neil's method to isSparse()
01a24af Improve isSparse()
4a5d92b Adjust coding style
97679fa Google Code Issue 155: lz4 cli should support sparse file https://code.google.com/p/lz4/issues/detail?id=155
fa27d23 Added support for multiple input files to act more like other compressors. For example: gzip file1 file2 file3. You can now do: lz4 [args] -m file1 file2 file3. Fixes 151.
67f3b41 Merge pull request #49 from t-mat/msvc-fseeki64
e68d1c9 restored lz4 hc compression ratio
41b6ed3 Replace fseek with _fseeki64 to avoid MSVC's 2GiB barrier
8f4e201 Fix : lz4frame.h within uninstaller
9fd92de Added : Visual project directory

git-subtree-dir: src/lz4
git-subtree-split: baf78e7e4dcbdf824a76f990ffeb573d113bbbdb
2015-05-29 15:03:27 -07:00
Tom Ritchford
e9d147f4b8 Set version to 0.28.2-b4 2015-05-29 13:45:23 -04:00
Tom Ritchford
f1a1ef49d5 Remove duplicate types. 2015-05-29 13:45:16 -04:00
Tom Ritchford
fd03c3297c Fix dangling pointer in websocketpp/error.hpp. 2015-05-29 13:45:07 -04:00
wilsonianb
ffd2e884f2 Clean up LedgerConsensus log message
Add missing space and use consistent pluralization.
2015-05-29 13:44:59 -04:00
Nik Bougalis
0d700d9833 Unsubscribe from normal data feeds on destruction 2015-05-29 13:44:52 -04:00
Nik Bougalis
dd902292ed Consensus cleanup:
* Inject dependencies, make functions free and levelize
* Add comments to document the intent behind the code
* Reduce class public interfaces
* Remove support for proposals without ledger hashes
2015-05-29 13:44:44 -04:00
seelabs
1b4e0f5f48 Tidying & Selectively forward manifests to peers:
* Do not forward manifests to peers that already know that manifest
* Do not forward historical manifests to peers
* Save/Load ValidatorManifests from a database
* Python test for setting ephmeral keys
* Cleanup manifest interface
2015-05-28 08:16:56 -07:00
Tom Ritchford
31d352b3aa Productionize manifest generator.
* Better output.
* Better error checking and reporting.
* Clearer names.
* Python style.
2015-05-28 07:22:34 -07:00
Tom Ritchford
c26b8124e5 Add original manifest.py. 2015-05-28 07:22:34 -07:00
Tom Ritchford
6bf7de2415 Add ecdsa Python library. 2015-05-28 07:22:33 -07:00
Tom Ritchford
18c51f4e4a Add ed25519 Python library. 2015-05-28 07:22:33 -07:00
Tom Ritchford
adf4860988 Move Python code to its own directory. 2015-05-28 07:22:33 -07:00
Josh Juran
0dd6b95ac2 Add Validator Manifests (RIPD-772):
A Validator Manifest allows validators to use a generated ed25519
secret key as a master key for generating new validator public/secret
key pairs. Using this mechanism, rippled instances trust the master
ed25519 public key instead of the now-ephemeral validator public key.

Through a new message and propagation scheme, this lets a validator
change its ephemeral public key without requiring that all rippled
instances on the network restart after maintaining the configuration
file.
2015-05-28 07:22:32 -07:00
Vinnie Falco
41a840e776 Tidying:
* Add missing includes
* Use preincrement
* Rearrange some declarations
* Fix some comments
2015-05-28 07:21:08 -07:00
Josh Juran
7d75041fb1 Fixes to cryptographic containers:
* Include Sign.cpp in unity builds
* Fix AnySecretKey publicKey and sign
* Make AnyPublicKey copyable
* Define op != for Slice
* Overload op << for Slice
* Overload op << for KeyType
2015-05-27 13:25:20 -07:00
Vinnie Falco
6675ee7f5c Set version to 0.28.2-b3 2015-05-22 11:12:44 -07:00
Howard Hinnant
155fcdbcd0 Change typedef to using.
Conflicts:
	src/ripple/app/TODO.md
	src/ripple/app/ledger/Ledger.h
	src/ripple/protocol/Protocol.h
2015-05-22 11:09:50 -07:00
Vinnie Falco
52f298f150 Tidy up app unity sources 2015-05-22 10:58:16 -07:00
Vinnie Falco
860ab3523c Refactor Ledger:
* Consolidate constructors
* Use pointer/size instead of Serializer
* Factor out PendingSaves
* Make some members free functions
* Reduce size of constructor initializer lists
2015-05-22 10:58:04 -07:00
Nik Bougalis
36ac3bc672 Set version to 0.28.2-b2 2015-05-21 14:51:46 -07:00
crazyquark
fc9ab12bf9 Add build instructions for Eclipse CDT + SConsolidator plugin. 2015-05-21 14:51:46 -07:00
Miguel Portilla
b39c1eb92c Require port in ips (RIPD-893) 2015-05-21 14:51:46 -07:00
JoelKatz
6994423a49 Don't consider broken peers candidates for history 2015-05-21 14:51:46 -07:00
JoelKatz
172e967a73 Latency-aware fetch pack target selection 2015-05-21 14:51:46 -07:00
Nik Bougalis
6f5d8bba2d Reduce STAmount public interface (RIPD-867):
* Implement subtraction as addition to the additive inverse
* Do not allow comparison with, addition to or subtraction from integers
* Remove unused functions
* Convert member functions to free functions
* Isolate unit-test specific code into the unit test
2015-05-21 14:51:41 -07:00
Nik Bougalis
67b18e4bea Check the fee early and return an error if it's malformed 2015-05-21 14:50:49 -07:00
Vinnie Falco
e932ba591f Set version to 0.28.2-b1 2015-05-20 13:24:13 -07:00
Vinnie Falco
f58399d2f3 Reduce thread count in static_initializer test (RIPD-864) 2015-05-20 13:24:13 -07:00
Nik Bougalis
730cd5d513 Cleanup consensus helper functions:
* Reduce public class interfaces
* Use free functions when possible
* Add self-documenting function return values
* Simplify ledger close resolution calculations
2015-05-20 13:24:12 -07:00
Edward Hennis
e838b30def Integration test to validate the WS ledger results.
* Also replace a couple of magic values with the relevant Tuning param.
2015-05-20 13:24:12 -07:00
Howard Hinnant
dddcc09378 Restrict access to data members. 2015-05-20 13:24:12 -07:00
JoelKatz
5adb68bba4 Easier way to get the validated ledger index 2015-05-20 13:24:12 -07:00
Scott Schurr
d6ef66646f 2-level transaction multi-signatures (RIPD-182):
This commit provides support for 2-level multi-signing of
transactions.  The ability is usually compiled out, since other
aspects of multi-signing are not yet complete.

Here are the missing parts:

 o Full support for Tickets in transactions.
 o Variable fees based on the number of signers,
 o Multiple SignerLists with access control flags on accounts,
 o Enable / disable operations based on access control flags,
 o Enable / disable all of multi-signing based on an amendment,
 o Integration tests, and
 o Documentation.
2015-05-20 13:24:06 -07:00
Scott Schurr
cf1638e6de sign_for RPC command (RIPD-182):
The sign_for RPC command returns a field suitable for
signing a multi-signed transaction.  Actual multi-signed
transactions are in the next commit.
2015-05-20 13:23:59 -07:00
Scott Schurr
64ebd64d2b SignerListSet txn and InnerObjectFormats (RIPD-182):
Add support for the SignerListSet transaction as a step toward
multi-sign support.

As part of the SignerListSet implementation, add InnerObjectFormat
templates (similar to TxFormats and LedgerFormats) and enforce them
in STObject, STArray, and STParsedJSON.
2015-05-20 13:23:52 -07:00
Scott Schurr
92799187ed Improvements to protocol serialization:
A few serialization changes coming from m-of-n development:

 o Improve readability of SField.cpp.
 o Better initialization of STObject.
 o Trimming of STObject public methods.
 o Add STObject::getFieldObject and STObject::setFieldObject.
 o Make STObject::isEquivalent more robust.
 o Improvements to whitespace, overrides, and virtuals.
2015-05-20 12:34:20 -07:00
Vinnie Falco
2f3834359e Modularize app/tx:
* Move LedgerView declaration
* Move CrossType
* Move Clock declaration
* Move Quality to protocol/
* Move Amounts to protocol/
* Move book to tx/impl
* Remove 0.27 legacy support
* Remove unused AmountType
* Remove core namespace
* Use STAmount
2015-05-20 12:34:19 -07:00
Miguel Portilla
399c43cae6 Set version to 0.28.1 2015-05-20 13:34:29 -04:00
Tom Ritchford
80acbe6f6b Change ArchLinux/PKGBUILD to have correct ripple build line. 2015-05-20 13:29:54 -04:00
Miguel Portilla
d90ba775e8 Require port in ips_fixed (RIPD-892) 2015-05-20 13:24:21 -04:00
Miguel Portilla
ea4161d880 Change example configuration protocol on loopback IP (RIPD-886) 2015-05-20 13:24:04 -04:00
Torrie Fischer
172a060330 circle: docker: Don't tag branches if its a PR (PKG-33) 2015-05-20 13:23:38 -04:00
Nik Bougalis
231efb5aa5 Set version to 0.28.1-rc3 2015-05-18 13:00:15 -07:00
JoelKatz
079475e491 Only touch InboundLedgers on success so failed acquires can expire 2015-05-18 13:00:15 -07:00
Tom Ritchford
aa775b4d3d Clean up rippled-example.cfg and update for new node_db settings 2015-05-18 13:00:00 -07:00
Nik Bougalis
216c8125e2 Expedite zero flow handling 2015-05-18 12:52:03 -07:00
Vinnie Falco
c61d0c663e Merge branch 'master' into develop 2015-05-13 13:29:54 -07:00
Nik Bougalis
0187c6a5a1 Set version to 0.28.0-hf2 2015-05-13 13:21:32 -07:00
Nik Bougalis
8289d4140a Correctly clamp when the taker balance is the limiting factor 2015-05-13 13:21:26 -07:00
Vinnie Falco
c7118a183a Set version to 0.28.1-rc2 2015-05-13 12:41:04 -07:00
JoelKatz
b1881e798b Control query depth based on latency:
This changes TMGetLedger protocol in a backward-compatible way to include
a "query depth" parameter - the number of extra levels in the SHAMap tree
that a server should return in the corresponding TMLedgerData. Depending
on the value or absence of the field, a server may adjust the amount of
returned data based on the observed latency of the requestor: higher
latencies will return larger data sets (to compensate for greater
request/response turnaround times).
2015-05-13 12:40:16 -07:00
Nik Bougalis
d44230b745 Correctly clamp when the taker balance is the limiting factor 2015-05-13 12:40:09 -07:00
Vinnie Falco
7b417b9d51 Set version to 0.28.1-rc1 2015-05-12 17:21:48 -07:00
Vinnie Falco
cc05e5727d Merge release into develop 2015-05-12 17:20:43 -07:00
Vinnie Falco
764a8f2644 Set version to 0.28.1-b10 2015-05-12 12:47:56 -07:00
JoelKatz
a15785eb64 Reduce severity of some logging messages 2015-05-12 12:47:56 -07:00
Vinnie Falco
688f8c5f3f Add historical ledger fetches per minute to get_counts 2015-05-12 12:47:56 -07:00
Vinnie Falco
dde5ccf7fa Add DecayWindow implementation 2015-05-12 12:47:55 -07:00
Vinnie Falco
d5a6313c71 Add RangeSet::lebesgue_sum 2015-05-12 09:50:12 -07:00
Vinnie Falco
f030aab759 Set version to 0.28.1-b9 2015-05-11 18:14:45 -07:00
JoelKatz
4393f98a2c History fetch changes:
* Don't pollute ledger cache with history
* Avoid race condition when getting ledger sequence numbers
* Make fetch packs larger
2015-05-11 18:14:45 -07:00
JoelKatz
c377d6c94b InboundLedgers improvements:
* Change findCreate to acquire
* Return Ledger rather than InboundLedger
2015-05-11 18:14:45 -07:00
JoelKatz
16aa015682 Fix off-by-one error in SHAMapNodeID:
Limit is 64 inner nodes at depth 0-63, and one leaf at depth 64
2015-05-11 18:14:45 -07:00
Miguel Portilla
9cded76cf0 Fix RPC ledger synchronization requirements:
* Better rules specific to each lookup case:
* By hash: Any ledger found by hash is valid.
* By numeric index: If rippled is out of sync, and the index is after the
* validated ledger, return "InsufficientNetworkMode" error.
* By named index: If rippled is out of sync, or closed/current is requested and significantly older than the validated ledger, return "InsufficientNetworkMode" error.
2015-05-11 18:14:45 -07:00
Vinnie Falco
4ad07bb6b2 Fix hops adjustment for validations 2015-05-11 18:14:45 -07:00
David Schwartz
d0b28a6700 Compute validated ledger age from signing time 2015-05-11 18:14:39 -07:00
Vinnie Falco
18299c3f7a Tidy up PeerSet:
* Move PeerSet to overlay/
* Remove unused functions
* Make some public members private
* Rename some functions
* Add comments
2015-05-11 12:06:14 -07:00
Miguel Portilla
ca07a1230b Add filtering to Account Objects (RIPD-868) 2015-05-11 11:58:35 -07:00
Edward Hennis
e0ad66d967 Fail Travis if scons vcxproj produces differences 2015-05-11 11:56:45 -07:00
seelabs
5615c4a2a7 Force scons to include soci version file:
Running `scons vcxproj` will sometimes include
soci's version.h and sometimes it will not. This
patch forces it to always include the file.
2015-05-11 11:56:42 -07:00
Nik Bougalis
d7fbef6764 Set version to 0.28.1-b8 2015-05-06 14:00:34 -07:00
JoelKatz
e95bda3bdf Peer latency tracking (RIPD-879):
Track peer latency, report in RPC, make peer selection for
fetching latency aware.

This also cleans up the PeerImp timer to minimize
resetting. Indirect routing is made latency-aware as well.
2015-05-06 13:38:59 -07:00
JoelKatz
c010a85ef5 Check the correct progress flag on transaction root node receipt 2015-05-06 13:38:59 -07:00
MarkusTeufelberger
798d36efcf Fix typo in LedgerMaster.cpp 2015-05-06 13:25:50 -07:00
Nik Bougalis
2d44c8568f Eliminate need for ledger in delivered_amount calculation (RIPD-860) 2015-05-06 13:25:50 -07:00
Nik Bougalis
7232bdb40c Reduce PeerFinder log verbosity 2015-05-06 13:25:50 -07:00
David Schwartz
45f092488a Simplify InboundLedger expiration (RIPD-873)
Let sweep logic remove obsolete ledger requests.
Touch inbound ledgers to prevent sweeping on requests.
Update sequence number if possible.
2015-05-06 13:25:50 -07:00
JoelKatz
4244e1070d Improvements to STParsedJSON:
* Cleanups and reduction of copying
* Add STArray::back, operator[], push_back(&&)
* Add make_stvar
* Rework STParsedJSON
* Fix code and unit tests that use STParsedJSON
* STTx move constructor
2015-05-06 13:11:24 -07:00
Nik Bougalis
5a7fa8cfa9 Reduce STAmount public interface (RIPD-867):
The STAmount class includes a number of functions which serve as thin
wrappers, which are unused or used only in one place, or which break
encapsulation by exposing internal implemenation details. Removing
such functions simplifies the interface of the class and ensures
consistency.

* getSNValue and getNValue are now free functions
* canonicalizeRound is no longer exposed
* Removed addRound and subRound
* Removed overloads of multiply, mulRound, divide and divRound
2015-05-06 13:11:24 -07:00
Josh Juran
daf4f8fcde Remove wallet_accounts and generator maps (RIPD-804):
* Remove the deprecated wallet_accounts command.
 * Remove dead code for generator maps.
 * Remove the help for the obsolete wallet_add and wallet_claim commands
   (which have already been removed).
2015-05-06 13:11:24 -07:00
Miguel Portilla
d182d1455e Relax RPC ledger synchronization requirements (RIPD-27, RIPD-840):
This enhances the reporting capability of RPC::LookupLedger and reduces
the requirement of a current ledger for many RPC commands.

The perceived up-time of client handlers improves since requests will
not depend on the server being fully synced.
2015-05-06 13:10:47 -07:00
Vinnie Falco
dc2260adbe Set version to 0.28.1-b7 2015-04-29 16:44:47 -07:00
Vinnie Falco
83a01e0c7d Set hopsAware version cutoff to 0.28.1-b7 2015-04-29 16:44:05 -07:00
Tom Ritchford
53c1269ebd Set version to 0.28.1-b6 2015-04-29 14:34:54 -04:00
Nik Bougalis
f8bfe3a550 Terminate process on SIGINT in all cases 2015-04-29 14:34:54 -04:00
Vinnie Falco
90bb53af20 Structured Overlay support for TTL limited messages:
When the [overlay] configuration key "expire" is set to 1, proposals
and validations will include a hops field. The hops is incremented with
each relay. Messages with a hop count will be dropped when they exceed
the TTL (Time to Live). Messages containing a hops field will not be
relayed or broadcast to older versions of rippled that don't understand
the field.

This change will not affect normal operation of the network or rippled
instances that do not set "expire" to 1.
2015-04-29 14:34:54 -04:00
Vinnie Falco
c77a2f335a Tidy up some business logic:
* Add OverlayImpl::for_each to tidy up some call sites
* Add comment about computing the unique ID for message routing
* Remove unused code
2015-04-29 14:34:53 -04:00
Vinnie Falco
8e34a1f6a7 Tidy up aged container declarations 2015-04-29 14:34:53 -04:00
Tom Ritchford
2564b62f5c Fix C++ style issues.
* Restrict files to 80 columns.
* Function names in GenerateDeterministicKey now start with lower case.
* Remove deprecated boost::format calls.
2015-04-29 14:34:53 -04:00
seelabs
a7598c5610 Remove unused database table (RIPD-755) 2015-04-29 14:34:52 -04:00
seelabs
8377f2516b Cache and apply account credits after payment processing (RIPD-821):
Credits made to any account during the processing of a payment are delayed until
the payment completes, enforcing a new invariant: liquidity for any paths
during a payment's execution may never increase. This eliminates the need for special
code to handle a variety of corner cases where consuming liquidity in one path
increases liquidity in others.
2015-04-29 14:34:52 -04:00
Vinnie Falco
7efd0ab0d6 Set version to 0.28.0 2015-04-24 18:57:36 -07:00
Vinnie Falco
14d38a1a8d Fix --rpc_ip and --rpc_port (RIPD-679)
This reverts commit 2b040569e7.
2015-04-24 18:57:04 -07:00
seelabs
c8447c190c Report the inbound listening port during crawl (RIPD-866) 2015-04-24 18:55:53 -07:00
Mark Travis
aa5d16b3d8 Skip inefficent SQL query (RIPD-870):
For large data sets the JOIN may not make forward progress in time.
This prevents the deletion of those entries in the database during
online delete. The number of such entries is very small compared to
the total size of the data anyway. A future version will address
this more thoroughly.
2015-04-24 18:55:49 -07:00
Vinnie Falco
fd1135315c Set version to 0.28.1-b5 2015-04-24 18:44:30 -07:00
Vinnie Falco
98c915b2ca Fix --rpc_ip and --rpc_port (RIPD-679)
This reverts commit 2b040569e7.
2015-04-24 18:44:30 -07:00
seelabs
9114f3d2e6 Report the inbound listening port during crawl (RIPD-866) 2015-04-24 18:19:10 -07:00
Mark Travis
5b0109055d Skip inefficent SQL query (RIPD-870):
For large data sets the JOIN may not make forward progress in time.
This prevents the deletion of those entries in the database during
online delete. The number of such entries is very small compared to
the total size of the data anyway. A future version will address
this more thoroughly.
2015-04-24 17:21:27 -07:00
Tom Ritchford
5a3168c9ff Set version to 0.28.1-b4 2015-04-23 16:47:23 -04:00
seelabs
a14f29f84f Remove obsolete code 2015-04-23 16:47:23 -04:00
Tom Ritchford
6c1190a361 Remove unnecessary thread in Soci (RIPD-862). 2015-04-23 16:47:22 -04:00
Howard Hinnant
100a76f0e8 Remove nested types SField::ref and SField::ptr...
* This silences a warning about a redundant cv-qualifier.
* This makes future coding mistakes about redundant
  cv-qualifiers much less likely.
* This makes the code easier to read.
2015-04-23 16:47:22 -04:00
JoelKatz
47482acf83 In consensus, get relative times from a steady clock (RIPD-859)
Using the system clock to get relative times for consensus
timing can result in performance issues if the system time
changes frequently.
2015-04-23 16:47:21 -04:00
Nik Bougalis
54ef4ee6ef Reduce severity level of offer cancellation logging 2015-04-23 16:47:20 -04:00
seelabs
2389abc295 Fix ownership of memory buffers in StatsDCollector (RIPD-756):
* Ownership of buffer memory in StatsDCollector is passed to the
boost::asio callback function. Before this, the memory may have been
freed before async_send was finished with the memory.
2015-04-23 16:47:20 -04:00
Nik Bougalis
67c666b033 Clean up LedgerEntrySet and TransactionEngine:
* Reduce public interfaces
* Remove wrapper functions
* Remove freeze timed cutover code
* Return results directly instead of via ref parameters
2015-04-23 16:47:19 -04:00
Vinnie Falco
5ce3ed3555 Set version to 0.28.1-b3 2015-04-21 14:01:44 -07:00
Nik Bougalis
d30b32fcde Set TX processing change date to 2015-05-12 13:00:00PDT 2015-04-21 14:01:25 -07:00
Miguel Portilla
568e4cebda Fix check for current ledger ID in RPC 2015-04-21 14:01:18 -07:00
Tom Ritchford
29d644e9d3 Fix WebSockets treatment of ping timer:
This solves a problem that caused a hang on shutdown related to
the lifetime of the ping timer completion handlers used in WebSockets.

* Turn the ping timer back on
* Use std::weak_ptr for WebSockets timer callbacks.
* Disable WebSocket pings if frequency in the .cfg is non-positive.
2015-04-21 14:01:13 -07:00
Torrie Fischer
2dbb7301fb Fix circleci 2015-04-21 14:01:09 -07:00
seelabs
d2cba1c54f Tidy up SQLite table creation:
* Check if tables and indexes exist
* Remove commands for unused table
2015-04-21 14:01:05 -07:00
seelabs
6a0c26a709 Fix return value when looking up non existent transactions 2015-04-21 14:01:00 -07:00
JoelKatz
e44ae6af93 Give ledger data requests their own job type:
This gives requests for ledger data (and transaction set data)
from peers a separate job type and prioritizes it appropriately.
Previously it was lumped in with fetch packs which have a low
concurrency limit. This should improve the performance of
retrieving historical information.
2015-04-21 14:00:54 -07:00
Vinnie Falco
837b0799ac Set version to 0.28.0-rc3 2015-04-21 13:48:39 -07:00
Nik Bougalis
bc85a8b24f Set TX processing change date to 2015-05-12 13:00:00PDT 2015-04-21 13:48:38 -07:00
Miguel Portilla
15d68649d5 Fix check for current ledger ID in RPC 2015-04-21 13:48:30 -07:00
Tom Ritchford
e0d96ae807 Fix WebSockets treatment of ping timer:
This solves a problem that caused a hang on shutdown related to
the lifetime of the ping timer completion handlers used in WebSockets.

* Turn the ping timer back on
* Use std::weak_ptr for WebSockets timer callbacks.
* Disable WebSocket pings if frequency in the .cfg is non-positive.
2015-04-21 12:26:11 -07:00
Torrie Fischer
3aa39ced60 Fix circleci 2015-04-21 12:23:23 -07:00
seelabs
1f1c0618e1 Tidy up SQLite table creation:
* Check if tables and indexes exist
* Remove commands for unused table
2015-04-21 12:21:27 -07:00
seelabs
7788aa25b5 Fix return value when looking up non existent transactions 2015-04-21 12:20:53 -07:00
JoelKatz
d5b460a85c Give ledger data requests their own job type:
This gives requests for ledger data (and transaction set data)
from peers a separate job type and prioritizes it appropriately.
Previously it was lumped in with fetch packs which have a low
concurrency limit. This should improve the performance of
retrieving historical information.
2015-04-21 12:15:59 -07:00
Vinnie Falco
9019f3a4f2 Set version to 0.28.1-b2 2015-04-20 15:57:02 -07:00
seelabs
dfda0d566a Support for boost 1.58 2015-04-20 15:55:48 -07:00
Vinnie Falco
99c2fac143 STVar: optimized storage for STObject (RIPD-825):
This introduces the STVar container, capable of holding any STBase-derived
class and implementing a "small string" optimization. STObject is changed
to store std::vector<STVar> instead of boost::ptr_vector<STBase>. This
eliminates a significant number of needless dynamic memory allocations and
deallocations during transaction processing when ledger entries are
deserialized. It comes at the expense of larger overall storage requirements
for STObject.
2015-04-20 15:54:26 -07:00
Nicholas Dudfield
4c5308da8d Update account_objects test:
* Use Request over json-rpc
* Use lodash to filter irrelevant fields from expectations
* Use LedgerState for state setup
* Test using limit and marker

Conflicts:
	test/account_objects-test.js
2015-04-20 15:54:14 -07:00
Miguel Portilla
4d0ed3d857 RPC account_objects (RIPD-777)
General RPC command that can retrieve objects in the account root.
  * Add account objects integration test.
  * Support tickets.

* Add removeElement in Json::Value
2015-04-20 15:54:09 -07:00
Vinnie Falco
0b5582ed0d Disable redundant ping timer 2015-04-20 15:52:38 -07:00
Tom Ritchford
17734f833c Revert "Checkpoint SOCI exactly every 1000 pages."
This reverts commit e874a2624f.
2015-04-20 15:52:33 -07:00
Vinnie Falco
98a9d5d424 Lower the severity of some PeerFinder logging 2015-04-20 15:52:29 -07:00
Vinnie Falco
6d74f36449 Fix Crawl handshake header parsing in Overlay 2015-04-20 15:52:20 -07:00
Vinnie Falco
47a5bf6aa5 Fix beast::ci_equal 2015-04-20 15:52:16 -07:00
Vinnie Falco
2805e9eb3b Set version to 0.28.0-rc2 2015-04-20 15:19:07 -07:00
Vinnie Falco
72a1a86886 Disable redundant ping timer 2015-04-20 13:42:00 -07:00
Tom Ritchford
ec190bae33 Revert "Checkpoint SOCI exactly every 1000 pages."
This reverts commit e874a2624f.
2015-04-20 11:01:23 -07:00
Vinnie Falco
83003e43d7 Lower the severity of some PeerFinder logging 2015-04-20 11:01:20 -07:00
Vinnie Falco
3b20dc2994 Fix Crawl handshake header parsing in Overlay 2015-04-20 11:00:03 -07:00
Vinnie Falco
a7198298e7 Fix beast::ci_equal 2015-04-20 10:59:58 -07:00
Vinnie Falco
f3d76d5780 Set version to 0.28.1-b1 2015-04-17 11:43:51 -07:00
Vinnie Falco
e2305c3c5e Merge branch 'release' into develop
Conflicts:
	Builds/rpm/rippled.spec
	src/ripple/protocol/impl/BuildInfo.cpp
2015-04-17 11:43:09 -07:00
Vinnie Falco
ba737d7e58 Set version to 0.28.0-rc1 2015-04-17 11:41:50 -07:00
Vinnie Falco
88f69204c8 Merge 0.28.0-b21 into release 2015-04-17 11:41:17 -07:00
Vinnie Falco
bb4561c2b8 Set version to 0.28.0-b22 2015-04-16 11:31:57 -07:00
seelabs
4710f764e4 Quiet unused variable warning 2015-04-16 11:31:57 -07:00
JoelKatz
11a59a767e Adjust cache parameters for 'huge' node size 2015-04-16 11:31:54 -07:00
Miguel Portilla
4cf3157aad Set version to 0.28.0-b21 2015-04-14 18:54:31 -04:00
Miguel Portilla
b1f6cb349b Improved parsing of universal port configuration settings (RIPD-856) 2015-04-14 18:51:53 -04:00
David Schwartz
0c134582ca Track peer "sanity" (RIPD-836)
* Each peer has a "sane/insane/unknown" status
* Status updated based on peer ledger sequence
* Status reported in peer json
* Only sane peers preferred for historical ledgers
* Overlay endpoints only accepted from known sane peers
* Untrusted proposals not relayed from insane peers
* Untrusted validations not relayed from insane peers
* Transactions from insane peers are not processed
* Periodically drop outbound connections to bad peers
* Bad peers get bootcache valence of zero

Peer "sanity" is based on the ledger sequence number they are on.  We
quickly become able to assess this based on current trusted validations.
We quarrantine rogue messages and disconnect bad outbound connections to
help maintain the configured number of good outbound connections.
2015-04-14 18:51:52 -04:00
Nik Bougalis
acf2833362 Set version to 0.28.0-b20 2015-04-13 10:24:47 -07:00
Nik Bougalis
20f9971096 Finalize date for switchover to 0.28.0 processing semantics 2015-04-13 10:24:47 -07:00
Nik Bougalis
cefeaceef0 Signal error for incorrect configuration during unit test 2015-04-13 10:24:47 -07:00
Howard Hinnant
1ba7c4b6ee Remove unneeded member initializer:
* This works around a clang bug.
* Also un-commented correctly deleted copy members.
2015-04-13 10:24:47 -07:00
Vinnie Falco
1b49776819 Add fetchBatch Backend interface 2015-04-10 19:14:57 -07:00
Vinnie Falco
41c68f4bbc Use static_initializer in KnownFormats singleton 2015-04-10 19:14:57 -07:00
Nik Bougalis
56ac830405 Refund owner's ticket reserve when a ticket is canceled (RIPD-855) 2015-04-10 19:12:51 -07:00
Nik Bougalis
ebcf821d81 Return descriptive error from account_currencies RPC (RIPD-806):
The 'account_index' field is expected to be an integer. If something
else is specified, the error message should clearly indicate which
field is at fault.
2015-04-10 19:11:28 -07:00
Tom Ritchford
e874a2624f Checkpoint SOCI exactly every 1000 pages. 2015-04-10 19:11:28 -07:00
Tom Ritchford
03d1c0ed21 Clean SOCI code.
* Throw exception rather than SEGV.
* Hide details of checkpointing from clients.
* Restrict to 80 columns and minor style tweaks.
2015-04-10 19:11:28 -07:00
Tom Ritchford
1b8c77eee0 Allow logging to be used outside the ripple namespace.
* Split logging macros over multiple lines.
* Restrict Log.h to 80 columns.
2015-04-10 19:11:28 -07:00
Tom Ritchford
d575cd50b1 Clean up Sustain.h and Sustain.cpp.
* Bring out magic numbers.
  * Get rid of boost::format.
2015-04-10 19:11:28 -07:00
Tom Ritchford
2b040569e7 Remove deprecated flags --rpc_ip and --rpc_port. 2015-04-10 19:11:28 -07:00
Miguel Portilla
7a53f86fff Compare current seq vs validated (RIPD-669) 2015-04-10 19:11:28 -07:00
Torrie Fischer
a90bb53cd2 Drop nexmo SMS support. Reverts 58b3cc1d. 2015-04-10 19:11:27 -07:00
Tom Ritchford
b450d62138 Port to Python: Build and run tests for multiple build configurations. 2015-04-10 19:11:27 -07:00
Nik Bougalis
1a9d65c52a Set version to 0.28.0-b19 2015-04-10 19:00:45 -07:00
seelabs
05f4746bbe Add workaround include for Windows.h NOMINMAX 2015-04-10 19:00:45 -07:00
seelabs
1c587723fa Safer macro restoration using MSVC extensions 2015-04-10 19:00:34 -07:00
Nik Bougalis
b2a9c79de5 Fix transaction enumeration in account_tx (RIPD-734):
In some corner cases, an incorrect resume marker could be
returned, preventing the complete enumeration of account
transactions.

* Robust markers via improved paging support
* New unit tests
* Cleanup
2015-04-10 19:00:22 -07:00
Nik Bougalis
64259c7bcb Better transaction analysis (RIPD-755):
The analysis of differences between locally built ledgers and consensus
ledgers is now more intelligent. Differences in these values will be
categorized:

 - Operation results
 - Transaction ordering
 - Generated metadata
2015-04-10 18:58:52 -07:00
Nik Bougalis
a7efdb4e52 Improve version switchover semantics:
* Support PreviousTxnID until the switchover
* Implement "No Ripple" for issue_iou and redeem_iou.
* Do not utilize issue_iou and redeem_iou from legacy code
* Rename 0.27.x legacy files to account for VS build process
* Misc. cleanups
2015-04-10 18:56:52 -07:00
Tom Ritchford
091ff0cce0 Set version to 0.28.0-b18 2015-03-31 21:50:45 -04:00
seelabs
7e25a3a942 Fix SQL in online delete cleanup:
* SQL statement is corrected to perform an implicit JOIN
* Add unit test
2015-03-31 21:50:45 -04:00
Nik Bougalis
b3254e2b18 Remove unsupported proof-of-work command parsing 2015-03-31 21:50:44 -04:00
JoelKatz
9a0fa79144 Fix duplication of full below cache and tree node cache 2015-03-31 21:50:43 -04:00
JoelKatz
352db260b2 STArray optimization 2015-03-31 21:50:43 -04:00
Nik Bougalis
f072b5b679 Avoid copying and improve optimization opportunities 2015-03-31 21:50:43 -04:00
JoelKatz
b4058a813b Small changes to improve transaction benchmarking:
* Set transaction valid in hash router correctly
* Properly account for root nodes in walkLedger
* If loaded ledger is insane, log details
* Extra logging while loading replay ledger
* Don't test unsigned transactions expecting them to succeed
* Don't be too noisy about signature failures
2015-03-31 21:50:42 -04:00
Vinnie Falco
b27e152ead NuDB: Enforce pool_thresh minimum of 1:
pool_thresh is prevented from going to zero. This solves a problem when
using callgrind where the CPU is monopolized, causing operations that
should complete quickly to take days.
2015-03-31 21:50:42 -04:00
Tom Ritchford
936e83759d Remove three warnings. 2015-03-31 21:50:41 -04:00
Tom Ritchford
18fdc175c6 Clean structure of RPC::addPaymentDeliveredAmount 2015-03-31 21:50:41 -04:00
JoelKatz
47c6ab0ced Reduce SHAMapTreeNode copying during SHAMap unsharing:
In some code paths, we bump the SHAMap sequence number
before we unshare. This forces SHAMapTreeNode to be
copied. By making the ledger immutable we cause the
unsharing to occur earlier, eliminating the copies.
2015-03-31 21:50:40 -04:00
seelabs
4868135d47 Improve build times:
* Get classic & unity sources once only
* Use MD5-Timestamp
* Use implicit cache for specific debug builds
* Skip prep work for targets what will not be built
2015-03-31 21:50:39 -04:00
Miguel Portilla
5e70db651d Improved local tx error messages (RIPD-720)
Failed local built transactions report the specific error.
2015-03-31 21:50:39 -04:00
David Schwartz
1fedede771 Remove transaction set acquire logic from consensus object
This creates a new InboundTransactions object that handles transaction sets,
removing this responsibility from the consensus object. The main benefit is
that many inbound transaction operations no longer require the master lock.

Improve logic to decide which peers to query, when to add more peers, and
when to re-query existing peers.
2015-03-31 21:50:38 -04:00
seelabs
00596f1436 Reduce memory allocation, remove some functions in Serializer. 2015-03-31 21:50:37 -04:00
Nik Bougalis
db840b5604 Perform Transactor checks early (RIPD-751):
Certain checks that determine if a transaction is malformed can be performed
without needing to look up accounts or access the ledger.

Perform those checks as early as possible to optimize transaction processing.
2015-03-31 06:49:53 -07:00
Nik Bougalis
45070d0e51 Reduce Transaction public interface 2015-03-30 13:05:42 -07:00
Tom Ritchford
8a1081f9ef Set version to 0.28.0-b17 2015-03-26 12:38:33 -04:00
seelabs
ac84e44161 Correct missing semicolons on sql statements 2015-03-26 12:38:33 -04:00
seelabs
836dfb6503 Do not log errors from initial database statements 2015-03-26 12:38:33 -04:00
Edward Hennis
35a8ce2349 Pathfinding unit tests:
* Refactor ripple path find to be more testable.
* Reimplements the first 4 tests from `tests\path-test.js`
* Verify balances in Ledger test.
2015-03-26 12:38:33 -04:00
Tom Ritchford
bb7d68b3b9 Add notes about Rippled's container classes. 2015-03-26 12:38:33 -04:00
Howard Hinnant
1979846e5e Change several uses of std::list to alternative containers:
*  Performance motivated.
*  Several of these called size() which is O(N) in gcc-4.8.
*  Remove container copy from LedgerConsensusImp::playbackProposals().
*  Addresses RIPD-284.
2015-03-26 12:38:33 -04:00
Howard Hinnant
a61ffab3f9 Remove unnecessary allocation/deallocation from masterLock
* Add make_lock.
* Rename Application::LockType to Application::MutexType:
* Rename getMasterLock to getMasterMutex.
* Use getMasterMutex and make_lock.
* Remove unused code.
2015-03-26 12:38:33 -04:00
Howard Hinnant
698fe73608 Move SHAMap hash computations from dirtyUp to walkSubTree
in order to reduce the total number of hash computations.
2015-03-26 12:38:33 -04:00
Josh Juran
0083c32629 Update VS project files 2015-03-26 12:38:33 -04:00
Nik Bougalis
f313caaa73 Set version to 0.28.0-b16 2015-03-19 07:55:19 -07:00
Edward Hennis
6e3f07ddce Remove unused / redundant functions. 2015-03-19 07:41:57 -07:00
Mark Travis
11d28c4856 Always increment payment pass counter 2015-03-19 07:41:57 -07:00
Nik Bougalis
e9394ca85a Implement "Default Ripple" logic in active direction:
When a balance change invokes trustCreate, we need to set the no ripple flag
if the "active" account's asfRippleDefault flag is cleared.
2015-03-19 07:41:57 -07:00
Nik Bougalis
9445a30e72 Implement "Default Ripple" logic in LedgerEntrySet::checkState 2015-03-19 07:41:57 -07:00
JoelKatz
185b1a3d36 Add noripple_check RPC command
To help gateways make the changes needed to adjust to the
"default ripple" flag, we've added the "noripple_check"
RPC command. This command tells gateways what they need
to do to set this flag and fix any trust lines created
before they set the flag.

Once your server is running and synchronized, you can run
the tool from the command line with a command like:
  rippled json noripple_check '
  {
    "account" : "<gateway_trusted_address_here>",
    "role" : "gateway",
    "transactions" : "true"
  }'

The server will respond with a list of "problems" that it
sees with the configuration of the account and its trust
lines. It will also return a "transactions" array suggesting
the transactions needed to fix the problems it found.
2015-03-19 07:41:57 -07:00
JoelKatz
1c2f5d60a5 Subscribe/Unsubscribe improvements:
* Don't acquire the master lock where it's not needed
* InfoSub tracks RT and validated accounts separately
* Correctly remove accounts from the InfoSub
2015-03-19 07:41:57 -07:00
JoelKatz
2f32910bef Reduce master lock scope in some RPC functions 2015-03-19 07:41:57 -07:00
JoelKatz
8de1b20bb5 Defer/avoid acquiring the master lock on proposals 2015-03-19 07:41:57 -07:00
David Schwartz
60a7abcef6 Decongest the master lock:
* Reduce scope of lock in ledger accept
* Remove duplicate tracking of transaction sets
* Need master lock to secure ledger sequencing
2015-03-19 07:41:57 -07:00
David Schwartz
e44e75fa6b Track and report peer load:
* PeerImp::charge only calls fail if dispatched from the peer
* Add "load" to output of RPC command "peer"
* Add Resource::Charge values for peer commands
* Impose some fee for every peer command
* Cleanup fee imposition
2015-03-19 07:41:57 -07:00
JoelKatz
ff7dc0b446 Reduce chatty log outputs 2015-03-19 07:41:57 -07:00
JoelKatz
f813cb2310 Tolerate LedgerSequence field in pseudo-transactions:
This will enable a forthcoming change to prevent pseudo-transactions
from reusing a transaction ID
2015-03-19 07:41:57 -07:00
JoelKatz
cba19d7e23 Document and cleanup ledger advance logic
* Don't acquire if validated ledger is old
* Don't try to publish if no valid ledger
* Update README.md file
2015-03-19 07:41:57 -07:00
Nicholas Dudfield
9479c0e12d Update uniport tests to use new config 2015-03-18 19:39:30 -07:00
Nicholas Dudfield
65c9c45ec6 Rename test file so npm test finds it 2015-03-18 19:39:30 -07:00
Miguel Portilla
6d79004d4f Better admin IP management in .cfg (RIPD-820):
* Deprecate rpc_admin_allow section from configuration file
* New port-specific setting 'admin':
  * Comma-separated list of IP addresses that are allowed administrative
    privileges (subject to username & password authentication if configured)
  * 127.0.0.1 is no longer a default admin IP.
  * 0.0.0.0 may be specified to indicate "any IP" but cannot be combined
    with other IP addresses.
2015-03-18 19:39:30 -07:00
seelabs
97623d20c5 Use soci in more places:
* Validator, peerfinder, SHAMapStore,
  RpcDB, TxnDB, LedgerDB, WalletDB use soci backend.
2015-03-18 19:39:26 -07:00
seelabs
d37802a42f Remove SqliteFactory. 2015-03-18 19:37:09 -07:00
seelabs
9b837a24aa Remove beast's sqdb module.
Conflicts:
	src/beast/beast/module/sqdb/api/backend.h
	src/beast/beast/module/sqdb/api/blob.h
	src/beast/beast/module/sqdb/api/into.h
	src/beast/beast/module/sqdb/api/session.h
	src/beast/beast/module/sqdb/api/statement.h
	src/beast/beast/module/sqdb/api/transaction.h
	src/beast/beast/module/sqdb/api/type_conversion_traits.h
	src/beast/beast/module/sqdb/api/use.h
	src/beast/beast/module/sqdb/detail/error_codes.h
	src/beast/beast/module/sqdb/detail/exchange_traits.h
	src/beast/beast/module/sqdb/detail/into_type.h
	src/beast/beast/module/sqdb/detail/once_temp_type.h
	src/beast/beast/module/sqdb/detail/prepare_temp_type.h
	src/beast/beast/module/sqdb/detail/ref_counted_prepare_info.h
	src/beast/beast/module/sqdb/detail/ref_counted_statement.h
	src/beast/beast/module/sqdb/detail/statement_imp.h
	src/beast/beast/module/sqdb/detail/type_conversion.h
	src/beast/beast/module/sqdb/detail/type_ptr.h
	src/beast/beast/module/sqdb/detail/use_type.h
	src/beast/beast/module/sqdb/sqdb.h
2015-03-18 19:37:08 -07:00
seelabs
d0ef2f7dd8 Use soci in some places:
* Brings the soci subtree into rippled.
* Validator, peerfinder, and SHAMapStore use new soci backend.
* Optional postgresql backend for soci (if POSTGRESQL_ROOT env var is set).
2015-03-18 19:37:08 -07:00
seelabs
c7cfd23580 Update sqlite3 to 3.8.8.2. 2015-03-18 19:37:03 -07:00
Vinnie Falco
7cf1ec3f89 Merge commit '9708a1260720d879d76a10f894925962f20611bc' as 'src/soci' 2015-03-18 19:36:00 -07:00
Vinnie Falco
9708a12607 Squashed 'src/soci/' content from commit 6e9312c
git-subtree-dir: src/soci
git-subtree-split: 6e9312c4bb3748907bd28d62c40feca42878cfef
2015-03-18 19:36:00 -07:00
Nik Bougalis
92812fe723 Set version to 0.27.4 2015-03-18 17:54:57 -07:00
JoelKatz
79417ac59a Limit passes in the payment engine to prevent endless looping:
This adds a limit of 1,000 passes to the payment engine. It protects against
possible cases where the execution of a pass fails to exhaust the liquidity
that made the pass possible or cases where two passes alternate providing
liquidity for each other.
2015-03-18 17:53:52 -07:00
Mark Travis
984f66e083 Don't VACUUM SQLite databases on startup with online delete enabled. 2015-03-18 17:53:42 -07:00
Tom Ritchford
ef2a436769 Set version to 0.28.0-b15 2015-03-16 20:54:17 -04:00
Edward Hennis
7f1a95550f Clean up unit test logs on success.
* Add a little bit of shell variable safety and tweak output.
2015-03-16 20:54:17 -04:00
seelabs
803f5b5613 Use buffer in STBlob 2015-03-16 20:54:15 -04:00
Nicholas Dudfield
8ca9fa1c26 Fix testutils.create_accounts
* Don't call ledger_wait inside parallel async loop
2015-03-16 20:54:14 -04:00
David Schwartz
3b3b897193 Add "Default Ripple" account flag and associated logic:
AccountSet set/clear, asfDefaultRipple = 8

AccountRoot flag, lsfDefaultRipple = 0x00800000

In trustCreate, set no ripple flag if appropriate.

If an account does not have the default ripple flag set,
new ripple lines created as a result of its offers being
taken or people creating trust lines to it have no ripple
set by that account's side automatically

Trust lines can be deleted if the no ripple flag matches
its default setting based on the account's default ripple
setting.

Fix default no-rippling in integration tests.
2015-03-16 20:54:14 -04:00
Torrie Fischer
6c364f63cc Build docker images on circleci based on travis.yml 2015-03-16 20:54:14 -04:00
seelabs
6b9e842ddd Replaces StringPairArray with Section in Config. 2015-03-16 20:54:13 -04:00
Nik Bougalis
8f88d915ba Support switchover from 0.27 to 0.28 processing semantics based on time:
Changes made to support autobridging and improve the offer-crossing and
pathfinding logic result in transaction-breaking changes which cause
incompatibilities between 0.27 and 0.28 builds of RippleD.

This patch simplifies deployment of 0.28 on the Ripple network by allowing
RippleD to emulate the 0.27 semantics while the last closed ledger closed
before March 30, 2015 at 13:00:00 PDT, after which time the new 0.28
semantics will become active.

The transaction-breaking changes addressed in this commit are:
    3ccbd7c9b2
    b203db27a4
2015-03-16 20:54:12 -04:00
JoelKatz
eaa1f47f00 Limit passes in the payment engine to prevent endless looping:
This adds a limit of 1,000 passes to the payment engine. It protects against
possible cases where the execution of a pass fails to exhaust the liquidity
that made the pass possible or cases where two passes alternate providing
liquidity for each other.
2015-03-16 20:54:11 -04:00
JoelKatz
cbeae85731 Fix specified destination issuer in pathfinding (RIPD-812)
* Compute the effective recipient.
* Make sure the effective recipient exists.
* Prohibit paths to the recipient, if not the effective recipient.
* Treat paths to the effective recipient as complete.
* Don't find looped paths.
* Use the effective recipient for getPathsOut weight.
2015-03-16 20:54:09 -04:00
Nik Bougalis
84e618b3f2 Improve pool seeding during startup:
* When starting up, we no longer rely just on the standard
  system RNG to generate entropy: we attempt to squeeze some
  from the execution state, and to recover any entropy that
  we had previously stored.

* When shutting down, if sufficient entropy has been accumulated
  attempt to store it for future use.
2015-03-16 20:54:08 -04:00
JoelKatz
382a16ff07 Avoid excess ledger header requests 2015-03-16 20:54:07 -04:00
JoelKatz
7bd339b645 Balance peer selection in getFetchPack 2015-03-16 20:54:07 -04:00
David Schwartz
70d8b2c4b7 getMissingNode performance and logging improvements 2015-03-16 20:54:07 -04:00
David Schwartz
3764a83c6b Ledger binary option
Conflicts:
	src/ripple/app/ledger/Ledger.cpp
	src/ripple/app/ledger/Ledger.h
	src/ripple/rpc/handlers/Ledger.cpp
2015-03-16 20:54:06 -04:00
Tom Ritchford
c3d200ddcd Set version to 0.28.0-b14 2015-03-13 11:21:02 -04:00
Tom Ritchford
44c5e337ab Remove obsolete comments from doc/CHANGELOG. 2015-03-13 11:21:02 -04:00
Nik Bougalis
040982e321 Only report 'delivered_amount' for executed payments (RIPD-827) 2015-03-13 11:21:00 -04:00
Nik Bougalis
6c81ea846c Calculate deep offer quality 2015-03-13 11:20:59 -04:00
Josh Juran
d082a0696d Support Ed25519 keys and signatures:
Recognize a new JSON parameter `key_type` in handlers for wallet_propose
and sign/submit.  In addition to letting the caller to specify either of
secp256k1 or ed25519, its presence prohibits the (now-deprecated) use of
heuristically polymorphic parameters for secret data -- the `passphrase`
parameter to wallet_propose will be not be considered as an encoded seed
value (for which `seed` and `seed_hex` should be used), and the `secret`
parameter to sign and submit will be obsoleted entirely by the same trio
above.

* Use constants instead of literals for JSON parameter names.
* Move KeyType to its own unit and add string conversions.
* RippleAddress
  * Pass the entire message, rather than a hash, to accountPrivateSign()
    and accountPublicVerify().
  * Recognize a 33-byte value beginning with 0xED as an Ed25519 key when
    signing and verifying (for accounts only).
  * Add keyFromSeed() to generate an Ed25519 secret key from a seed.
  * Add getSeedFromRPC() to extract the seed from JSON parameters for an
    RPC call.
  * Add generateKeysFromSeed() to produce a key pair of either type from
    a seed.
* Extend Ledger tests to cover both key types.
2015-03-12 21:53:59 -07:00
Nik Bougalis
f999839e59 Set version to 0.27.3-sp2 2015-03-12 13:37:47 -07:00
JoelKatz
f1bc662a24 Add noripple_check RPC command
To help gateways make the changes needed to adjust to the
"default ripple" flag, we've added the "noripple_check"
RPC command. This command tells gateways what they need
to do to set this flag and fix any trust lines created
before they set the flag.

Once your server is running and synchronized, you can run
the tool from the command line with a command like:
  rippled json noripple_check '
  {
    "account" : "<gateway_trusted_address_here>",
    "role" : "gateway",
    "transactions" : "true"
  }'

The server will respond with a list of "problems" that it
sees with the configuration of the account and its trust
lines. It will also return a "transactions" array suggesting
the transactions needed to fix the problems it found.
2015-03-12 13:37:06 -07:00
Nik Bougalis
232693419a Set version to 0.27.3-sp1 2015-03-11 10:26:39 -07:00
Nicholas Dudfield
ed66b951c6 Fix testutils.create_accounts
* Don't call ledger_wait inside parallel async loop
2015-03-11 10:25:27 -07:00
Nik Bougalis
70c2854f7c Set version to 0.27.3 2015-03-10 14:06:33 -07:00
David Schwartz
e9381ddeb2 Add "Default Ripple" account flag and associated logic:
AccountSet set/clear, asfDefaultRipple = 8

AccountRoot flag, lsfDefaultRipple = 0x00800000

In trustCreate, set no ripple flag if appropriate.

If an account does not have the default ripple flag set,
new ripple lines created as a result of its offers being
taken or people creating trust lines to it have no ripple
set by that account's side automatically

Trust lines can be deleted if the no ripple flag matches
its default setting based on the account's default ripple
setting.

Fix default no-rippling in integration tests.
2015-03-10 14:05:18 -07:00
Tom Ritchford
1b46e003c3 Set version to 0.28.0-b13 2015-03-09 17:49:39 -04:00
Howard Hinnant
4611d5a35f Remove unused SyncUnorderedMap 2015-03-09 17:49:39 -04:00
Nicholas Dudfield
2e59378ab7 Fix AppVeyor:
* Detect continuous integration environment via `CI` variable
* Use double quotes for build cache path
2015-03-09 17:49:39 -04:00
JoelKatz
fc8bf39043 Simplify tracking of recently requested ledger entries
Instead of tracking recently-requested entries from inbound
ledgers by node ID, track by hash. This allows state and
transaction entries to be tracked in the same set.
2015-03-09 17:49:38 -04:00
Vinnie Falco
2cccd8ab28 Fix gentex usage in nudb 2015-03-09 17:49:37 -04:00
Vinnie Falco
d537ceedd6 Tidy up nudb:
* Define WIN32_LEAN_AND_MEAN before including Windows.h
* Remove unnecessary template argument
* Rename to identity
* Make identity default api codec
2015-03-09 17:49:37 -04:00
Tom Ritchford
ac7243b309 Remove unused static function. 2015-03-02 17:40:12 -05:00
Tom Ritchford
607e983f37 Set version to 0.28.0-b12 2015-03-02 16:50:01 -05:00
Mark Travis
02f7326b7e Remove orphan function. 2015-03-02 16:50:01 -05:00
Edward Hennis
b688f69031 Builds/test-only.sh will build and test by scons target.
* test-all.sh simplified to call test-only.sh.
* Script fails if build or tests fail. Allows chaining and git bisect run.
* Add copyright notice
* Ignore gprof performance data created by testing the profile builds.
2015-03-02 16:50:00 -05:00
Tom Ritchford
df41329df9 Replace "it's" with "its" in several places. 2015-03-02 16:49:59 -05:00
Tom Ritchford
0825bd7076 Cleanups to Json Object code.
* Replace Json::JsonException with std::logic_error.
* Move two functions definitions to Object.cpp.
* Fix include guards.
2015-03-02 16:49:56 -05:00
Tom Ritchford
e9b7003cf5 Move streaming Json objects to ripple/json. 2015-03-02 16:49:56 -05:00
Tom Ritchford
c5d673c426 Better integration between JsonObject and Json::Value. 2015-03-02 16:49:56 -05:00
Nik Bougalis
9cc8eec773 Set version to 0.27.2 2015-03-01 14:56:44 -08:00
Nik Bougalis
0b45535061 Calculate deep offer quality 2015-02-28 13:28:54 -08:00
Tom Ritchford
9f64ad8d89 Add WebSocket 04 interface.
* New WebSocket04 traits class implements strategies.
* New "websocket_version" configuration setting selects between 0.2 and 0.4.
2015-02-28 14:57:38 -05:00
Tom Ritchford
e5b0b7e9a7 Expose a method and add a handler in websocketpp.
* Expose websocketpp::transport::asio::connection::get_strand().
* Add new send_empty_handler to websocketpp::endpoint.
2015-02-28 14:57:38 -05:00
Tom Ritchford
9c3522cb70 Isolate WebSocket 0.2-specific code.
* Hide implementation details of the WebSocket server from clients.
* Extract a generic traits class.
2015-02-28 14:57:38 -05:00
Tom Ritchford
b357390215 Remove redundant post to strand in websocket. 2015-02-27 12:11:54 -05:00
Tom Ritchford
c66fc2f656 Rename all WebSocket code into one directory. 2015-02-27 12:11:54 -05:00
Tom Ritchford
64554aca6d Set version to 0.28.0-b11 2015-02-26 21:02:39 -05:00
Nik Bougalis
f1df9a02fa Fix declaration/implementation mismatches 2015-02-26 21:02:38 -05:00
JoelKatz
f3725bdd2e Return a validated ledger if there is one (RIPD-814)
LedgerMaster::getLedgerBySeq should return a validated
ledger (rather than the the open or closed ledger) for
a sequence number for which it has a fully-validated ledger.
2015-02-26 21:02:37 -05:00
Tom Ritchford
cb92b94d55 Remove unused variable. 2015-02-26 21:02:36 -05:00
Vinnie Falco
ef01f82e0c Add nounity targets to msvc projects 2015-02-26 21:02:35 -05:00
Vinnie Falco
4ba7ee8c92 Support per-target ExcludeFromBuild in VSProject 2015-02-26 21:02:35 -05:00
Howard Hinnant
c59633a588 Make SHAMap::fetchNodeFromDB const
When fetchNodeFromDB discovers a missing node in the database it
must reset the ledger sequence to 0.  By treating this as a logically
const operation, even though not physically const, many other member
functions can be made const, including compare.
2015-02-26 21:02:33 -05:00
Vinnie Falco
f56e37398c Always use HTTP handshaking in overlay:
Inbound and outbound peer connections always use HTTP handshakes to
negotiate connections, instead of the deprecated TMHello protocol
message.

rippled versions 0.27.0 and later support both optional HTTP handshakes
and legacy TMHello messages, so always using HTTP handshakes should not
cause disruption. However, versions before 0.27.0 will no longer be
able to participate in the overlay network - support for handshaking
via the TMHello message is removed.
2015-02-26 21:02:32 -05:00
Tom Ritchford
e43ffa6f2b Set version to 0.28.0-b10 2015-02-25 20:26:12 -05:00
Yana
6991bc9723 Spelling corrections 2015-02-25 20:26:12 -05:00
Miguel Portilla
9d6106a80b Require boost 1.57 2015-02-25 20:26:12 -05:00
Tom Ritchford
9e70404411 Get rid of compilation warning. 2015-02-25 20:26:12 -05:00
Nik Bougalis
bc48d299b6 Report server versions when crawling the overlay network 2015-02-25 20:26:12 -05:00
mDuo13
a8db5650a5 Add online_delete reminder to ledger_history in example cfg 2015-02-25 19:56:47 -05:00
Nicholas Dudfield
91871b418b Changes to Universal Port:
* Add tests
* Introduce requestRole helper
* Always honor admin=no
* Welcome guests anywhere admin privileges aren't required
2015-02-25 19:46:56 -05:00
Tom Ritchford
aaf98082e9 Set version to 0.28.0-b9 2015-02-24 20:28:43 -05:00
Tom Ritchford
ac228deeda Replace LEDGER_JSON_ macros with an enum. 2015-02-24 20:28:43 -05:00
Edward Hennis
fc661c83ef Build and run tests on all available build types
* Tests include unit and integration (npm)
2015-02-24 20:28:43 -05:00
Vinnie Falco
a2acffdfa3 New serialized object, public key, and private key interfaces
This introduces functions get and set, and a family of specialized
structs called STExchange. These interfaces allow efficient and
seamless interchange between serialized object fields and user
defined types, especially variable length objects.

A new base class template TypedField is mixed into existing SField
declarations to encode information on the field, allowing template
metaprograms to both customize interchange based on the type and
detect misuse at compile-time.

New types AnyPublicKey and AnySecretKey are introduced. These are
intended to replace the corresponding functionality in the deprecated
class RippleAddress. Specializations of STExchange for these types
are provided to allow interchange. New free functions verify and sign
allow signature verification and signature generation for serialized
objects.

* Add Buffer and Slice primitives
* Add TypedField and modify some SField
* Add STExchange and specializations for STBlob and STInteger
* Improve STBlob and STInteger to support STExchange
* Expose raw data in RippleAddress and Serializer
2015-02-24 20:28:43 -05:00
David Schwartz
79ce4ed226 Document cluster configuration and monitoring (RIPD-732) 2015-02-24 20:28:43 -05:00
Nik Bougalis
e3a7aa0033 Constrain valid inputs for memo fields (RIPD-712) 2015-02-24 20:25:34 -05:00
Vinnie Falco
95973ba3e8 Set version to 0.27.1 2015-02-24 13:31:13 -08:00
Tom Ritchford
fde6303ae6 Set version to 0.28.0-b8 2015-02-24 12:33:59 -05:00
Vinnie Falco
b4a1948951 Use all parts of suite name to detect duplicates 2015-02-24 12:33:59 -05:00
Miguel Portilla
b927028416 Display human readable SSL error codes 2015-02-24 12:33:59 -05:00
Tom Ritchford
fe5d1ff6c5 Set version to 0.28.0-b7 2015-02-23 11:53:21 -08:00
Yana
1308656000 Update README.md file (RIPD-802) 2015-02-23 11:53:20 -08:00
Howard Hinnant
ec1e6b9385 Cleanup and simplifications to SHAMap:
SHAMapTreeNode
* Remove SHAMapTreeNode::pointer and SHAMapTreeNode::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapTreeNode declaration.
* Make clear what part of SHAMapTreeNode is:
  1) Truly public.
  2) Used only by SHAMap.
  3) Truly private to SHAMapTreeNode.

SHAMapItem
* Remove SHAMapItem::pointer and SHAMapItem::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapItem declaration.
* Make clear what part of SHAMapItem is:
  1) Truly public.
  2) Used only by SHAMapTreeNode.
  3) Truly private to SHAMapItem.

SHAMapSyncFilter
* Add override for SHAMapSyncFilter-derived functions.
* Add missing header.
* Default the destructor and delete the SHAMapSyncFilter copy members.

SHAMapNodeID
* Remove unused mHash member.
* Remove unused std::hash and boost::hash specializations.
* Remove unused constructor.
* Remove unused comparison with uint256.
* Remove unused getNodeID (int depth, uint256 const& hash).
* Remove virtual specifier from getString().
* Fix operator<= and operator>=.
* Document what API is used outside of SHAMap.
* Move inline definitions outside of the class declaration.

SHAMapMissingNode
* Make SHAMapType a enum class to prevent unwanted conversions.
* Remove needless ~SHAMapMissingNode() declaration/definition.
* Add referenced std includes.

SHAMapAddNode
* Make SHAMapAddNode (int good, int bad, int duplicate) ctor private.
* Move all member function definitions out of the class declaration.
* Remove dependence on beast::lexicalCastThrow.
* Make getGood() const.
* Make get() const.
* Add #include <string>.

SHAMap
* Remove unused enum STATE_MAP_BUCKETS.
* Remove unused getCountedObjectName().
* Remove SHAMap::pointer
* Remove SHAMap::ref
* Remove unused fetchPackEntry_t.
* Remove inline member function definitions from class declaration.
* Remove unused getTrustedPath.
* Remove unused getPath.
* Remove unused visitLeavesInternal.
* Make SHAMapState an enum class.
* Explicitly delete SHAMap copy members.
* Reduce access to nested types as much as possible.
* Normalize member data names to one style.

* Change last of the typedefs to usings under shamap.
* Reorder some includes ripple-first, beast-second.
* Declare a few constructions from make_shared with auto.
* Mark those SHAMap member functions which can be, with const.

* Add missing includes
2015-02-23 11:44:57 -08:00
Tom Ritchford
315a8b6b60 Use jss for many Json fields.
* Document JsonFields.
  * Remove some unused JsonFields values.
2015-02-23 14:36:34 -05:00
Nik Bougalis
558c6b621b Clean up JSON code:
* Remove obsolete files
* Remove obsolete preprocessor configuration tags and decorations
* Remove arcane functionality (YAML compatibility, comment support)
* Enforce strict mode (single root)
* Improve parsing of numerical types
* Misc. cleanups
2015-02-23 14:36:34 -05:00
Edward Hennis
6d91d02c62 Unit test simulated ledgers can do signature verification. 2015-02-23 14:34:37 -05:00
Josh Juran
436ded68b7 Add unit tests for wallet keypair generation:
* Allow `passphrase` to be a seed encoded in any of three formats or a
    literal passphrase.
  * Recognize the absence of `passphrase` as requesting a random seed.

Extract walletPropose() and keypairForSignature() as separately factored
functions (from doWalletPropose() and transactionSign() respectively) to
facilitate unit testing.
2015-02-23 14:34:35 -05:00
JoelKatz
3ec88b3665 Implement getFetchPack using visitDifferences 2015-02-23 14:34:34 -05:00
Tom Ritchford
2caedb38a6 Set version to 0.28.0-b6 2015-02-18 13:31:31 -05:00
Vinnie Falco
49378ab7fe Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that
was destroyed. This changes buffers_type::iterator to point to the
original streambuf instead, which always outlives the iterator.
2015-02-18 13:31:18 -05:00
Vinnie Falco
982dc6aa8c Reject invalid requests on peer port sooner. 2015-02-18 13:31:18 -05:00
Mark Travis
33175187b7 Don't VACUUM SQLite databases on startup with online delete enabled. 2015-02-18 13:31:18 -05:00
Tom Ritchford
0339904920 Update nudb comments. 2015-02-18 13:31:18 -05:00
Vinnie Falco
8bda9487c6 Add shamap::Family injection bundle 2015-02-18 13:31:18 -05:00
seelabs
617d84c0ef BasicConfig support for legacy values:
* A legacy value is a config section with a single-line.
* These values may be read from the BasicConfig interface so
  the deprecated Config class does not need to be exposed to
  clients.
* Made Config class more testable.
2015-02-18 13:31:18 -05:00
Vinnie Falco
ac64731d55 Set version to 0.27.1-rc3 2015-02-12 12:59:48 -08:00
Vinnie Falco
5dc064e971 Revert "Disable Overlay socket handoffs"
This reverts commit 8eb05d0950.
2015-02-12 12:59:48 -08:00
Vinnie Falco
c24732ed4e Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that
was destroyed. This changes buffers_type::iterator to point to the
original streambuf instead, which always outlives the iterator.
2015-02-12 12:59:35 -08:00
Vinnie Falco
ba710bee86 Reject invalid requests on peer port sooner. 2015-02-12 12:43:42 -08:00
Vinnie Falco
c20392ca80 Set version to 0.27.1-rc2 2015-02-11 20:53:27 -08:00
Vinnie Falco
8eb05d0950 Disable Overlay socket handoffs 2015-02-11 20:53:27 -08:00
Tom Ritchford
b11ad375cd Set version to 0.28.0-b5 2015-02-11 20:42:38 -05:00
Josh Juran
7a6d533014 Refactor GenerateDeterministicKey and its call sites:
Remove the use of ec_key parameters and return values from ECDSA crypto
prototypes.  Don't store key data into an ec_key variable only to fetch
it back into the original type again.  Use uint256 and Blob explicitly.

Pass private keys as uint256, and pass public keys as either pointer and
length or Blob in calls to ECDSA{Sign,Verify}() and {en,de}cryptECIES().

Replace GenerateRootDeterministicKey() with separate functions returning
either the public or private key, since no caller needs both at once.

Simplify the use of GenerateDeterministicKey within RippleAddress.  Call
a single routine rather than pass the result of one as input to another.

Add openssl unit with RAII classes for bignum, bn_ctx, and ec_point plus
free utility functions.

Rewrite the functions in GenerateDeterministicKey.cpp to use RAII rather
than explicit cleanup code:
  * factor out secp256k1_group and secp256k1_order for reuse rather than
    computing them each time
  * replace getPublicKey() with serialize_ec_point(), which makes, sets,
    and destroys an ec_key internally (sparing the caller those details)
    and calls i2o_ECPublicKey() directly
  * return bignum rather than ec_key from GenerateRootDeterministicKey()
  * return ec_point rather than EC_KEY* from GenerateRootPubKey()

Move ECDSA{Private,Public}Key() to a new ECDSAKey unit.
Move ec_key.h into impl/ since it's no longer used outside crypto/.

Remove now-unused member functions from ec_key.

Change tabs to spaces; trim trailing whitespace (including blank lines).
2015-02-11 20:42:38 -05:00
Howard Hinnant
be44f75d2d Add missing includes. 2015-02-11 20:42:38 -05:00
Vinnie Falco
ab14123aed Remove obsolete classes:
Legacy workarounds for Visual Studio non thread-safe initialization
of function local objects with static storage duration are removed:

* Remove LeakChecked
* Remove StaticObject
* Remove SharedSingleton
2015-02-11 20:42:38 -05:00
Tom Ritchford
a963a6d10d Add noexcept qualifier to swaps and moves. 2015-02-11 20:42:38 -05:00
Vinnie Falco
69b4cd22a2 Speed up some unit tests:
A few of the slowest unit tests are modified to process a smaller data
set size, to reduce the time required to run all unit tests.
2015-02-11 20:14:44 -05:00
Vinnie Falco
958325653f Add elapsed time report for unit test runner:
When unit tests are complete, the longest running tests if any are logged.
2015-02-11 20:14:44 -05:00
Josh Juran
c5dc419f9e Remove unused source file 2015-02-11 20:14:44 -05:00
Vinnie Falco
2a201f9525 Add RocksDB to nudb import tool (RIPD-781,785):
This custom tool is specifically designed for very fast import of
RocksDB nodestore databases into NuDB.
2015-02-11 20:14:44 -05:00
Vinnie Falco
b7ba509618 NuDB: Use nodeobject codec in Backend (RIPD-793):
This adds codecs for snappy and lz4, and a new nodeobject codec. The
nodeobject codec provides a highly efficient custom compression scheme
for inner nodes, which make up the majority of nodestore databases.
Non inner node objects are compressed using lz4.

The NuDB backend is modified to use the nodeobject codec. This change
is not backward compatible - older NuDB databases cannot be opened or
imported.
2015-02-11 14:41:33 -08:00
Vinnie Falco
f946d7b447 Remove obsolete NodeObject fields:
Legacy fields of NodeObject are removed, as they are no longer
used and there is a space savings from omitting them:

* Remove LedgerIndex
2015-02-11 14:41:32 -08:00
Vinnie Falco
e2a5535ed6 NuDB: Performance improvements (RIPD-793,796):
This introduces changes in nudb to improve speed, reduce database size,
and enhance correctness. The most significant change is to store hashes
rather than entire keys in the key file. The output of the hash function
is reduced to 48 bits, and stored directly in buckets.

The API is also modified to introduce a Codec parameter allowing for
compression and decompression to be supported in the implementation
itself rather than callers.

THe data file no longer contains a salt, as the salt is applicable
only to the key and log files. This allows a data file to have multiple
key files with different salt values. To distinguish physical files
belonging to the same logical database, a new field UID is introduced.
The UID is a 64-bit random value generated once on creation and stored
in all three files.

Buckets are zero filled to the end of each block, this is a security
measure to prevent unintended contents of memory getting stored to
disk. NuDB offers the varint integer type, this is identical to
the varint described by Google.

* Add varint
* Add Codec template argument
* Add "api" convenience traits
* Store hash in buckets
* istream can throw short read errors
* Support std::uint8_t format in streams
* Make file classes part of the public interface
* Remove buffers pessimization, replace with buffer
* Consolidate creation utility functions to the same header
* Zero fill unused areas of buckets on disk
* More coverage and improvements to the recover test
* Fix file read/write to loop until all bytes processed
* Add verify_fast, faster verify for large databases

The database version number is incremented to 2; older databases can
no longer be opened and should be deleted.
2015-02-11 14:41:31 -08:00
Vinnie Falco
0f94e2c0c3 Set version to 0.27.1-rc1 2015-02-10 16:22:14 -08:00
Vinnie Falco
a25508b98d Add RocksDB to nudb import tool (RIPD-781,785):
This custom tool is specifically designed for very fast import of
RocksDB nodestore databases into NuDB.
2015-02-10 16:22:14 -08:00
Vinnie Falco
e825433a38 NuDB: Use nodeobject codec in Backend (RIPD-793):
This adds codecs for snappy and lz4, and a new nodeobject codec. The
nodeobject codec provides a highly efficient custom compression scheme
for inner nodes, which make up the majority of nodestore databases.
Non inner node objects are compressed using lz4.

The NuDB backend is modified to use the nodeobject codec. This change
is not backward compatible - older NuDB databases cannot be opened or
imported.
2015-02-10 16:22:13 -08:00
Vinnie Falco
d1c08889fe Remove obsolete NodeObject fields:
Legacy fields of NodeObject are removed, as they are no longer
used and there is a space savings from omitting them:

* Remove LedgerIndex
2015-02-10 16:22:13 -08:00
Vinnie Falco
0b82b5a0d6 NuDB: Performance improvements (RIPD-793,796):
This introduces changes in nudb to improve speed, reduce database size,
and enhance correctness. The most significant change is to store hashes
rather than entire keys in the key file. The output of the hash function
is reduced to 48 bits, and stored directly in buckets.

The API is also modified to introduce a Codec parameter allowing for
compression and decompression to be supported in the implementation
itself rather than callers.

THe data file no longer contains a salt, as the salt is applicable
only to the key and log files. This allows a data file to have multiple
key files with different salt values. To distinguish physical files
belonging to the same logical database, a new field UID is introduced.
The UID is a 64-bit random value generated once on creation and stored
in all three files.

Buckets are zero filled to the end of each block, this is a security
measure to prevent unintended contents of memory getting stored to
disk. NuDB offers the varint integer type, this is identical to
the varint described by Google.

* Add varint
* Add Codec template argument
* Add "api" convenience traits
* Store hash in buckets
* istream can throw short read errors
* Support std::uint8_t format in streams
* Make file classes part of the public interface
* Remove buffers pessimization, replace with buffer
* Consolidate creation utility functions to the same header
* Zero fill unused areas of buckets on disk
* More coverage and improvements to the recover test
* Fix file read/write to loop until all bytes processed
* Add verify_fast, faster verify for large databases

The database version number is incremented to 2; older databases can
no longer be opened and should be deleted.
2015-02-10 16:22:13 -08:00
Vinnie Falco
a33d0d4fb6 Add general delimiter split() to rfc2616 2015-02-08 19:43:37 -08:00
Vinnie Falco
ba42334d36 Add lz4
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
2015-02-08 19:43:26 -08:00
Vinnie Falco
dad460dcfc Squashed 'src/lz4/' content from commit e25b51d
git-subtree-dir: src/lz4
git-subtree-split: e25b51de7b51101e04ceea194dd557fcc23c03ca
2015-02-08 19:43:04 -08:00
Vinnie Falco
2e62641aa4 Merge commit 'dad460dcfc8466a8e1c59529d490829fcfaeee73' as 'src/lz4' 2015-02-08 19:43:04 -08:00
Vinnie Falco
3ae23b6a54 Remove spurious call to fetch in NuDBBackend 2015-02-08 19:42:07 -08:00
Vinnie Falco
97126f18b1 Add /crawl cgi request feature to peer protocol (RIPD-729):
This adds support for a cgi /crawl request, issued over HTTPS to the configured
peer protocol port. The response to the request is a JSON object containing
the node public key, type, and IP address of each directly connected neighbor.
The IP address is suppressed unless the neighbor has requested its address
to be revealed by adding "Crawl: public" to its HTTP headers. This field is
currently set by the peer_private option in the rippled.cfg file.
2015-02-08 19:42:01 -08:00
Vinnie Falco
3838d222c2 NuDB: limit size of mempool (RIPD-787):
Insert now blocks when the size of the memory pool exceeds a predefined
threshold. This solves the problem where sustained insertions cause the
memory pool to grow without bound.
2015-02-08 19:41:54 -08:00
Vinnie Falco
96c3292210 Add missing include 2015-02-08 19:41:48 -08:00
Vinnie Falco
b0fd92cb3f Fix unsafe iterator dereference in PeerFinder 2015-02-08 19:41:43 -08:00
Vinnie Falco
62c5b5e570 Add general delimiter split() to rfc2616 2015-02-07 15:19:55 -08:00
Vinnie Falco
feaa0871ac Add lz4 2015-02-07 06:38:37 -08:00
Vinnie Falco
9f41976926 Merge commit '1784f24c5f81e864bf0ad8dcfdf4266ca1108290' as 'src/lz4' 2015-02-05 15:40:04 -08:00
Vinnie Falco
1784f24c5f Squashed 'src/lz4/' content from commit e25b51d
git-subtree-dir: src/lz4
git-subtree-split: e25b51de7b51101e04ceea194dd557fcc23c03ca
2015-02-05 15:40:04 -08:00
Vinnie Falco
fc47d9fc4d Set version to 0.28.0-b4 2015-02-03 16:24:34 -08:00
Vinnie Falco
eade9f8f2b Revert RocksDB backend settings:
This reverts the change that makes RocksDBQuick the default settings for
node_db "type=rocksdb". The quick settings can be obtained by setting
"type=rocksdbquick".

RocksDBQuick settings are implicated in memory over-utilization problems
seen recently.
2015-02-03 16:24:34 -08:00
Vinnie Falco
6276c55cc9 Set version to 0.27.0-sp1 2015-02-03 14:58:02 -08:00
Vinnie Falco
afa6ff7c4b Revert RocksDB backend settings:
This reverts the change that makes RocksDBQuick the default settings for
node_db "type=rocksdb". The quick settings can be obtained by setting
"type=rocksdbquick".

RocksDBQuick settings are implicated in memory over-utilization problems
seen recently.
2015-02-03 14:57:54 -08:00
Vinnie Falco
f4dcbe3a84 Remove spurious call to fetch in NuDBBackend 2015-02-03 12:56:35 -08:00
Vinnie Falco
9c02cc1b17 Add /crawl cgi request feature to peer protocol (RIPD-729):
This adds support for a cgi /crawl request, issued over HTTPS to the configured
peer protocol port. The response to the request is a JSON object containing
the node public key, type, and IP address of each directly connected neighbor.
The IP address is suppressed unless the neighbor has requested its address
to be revealed by adding "Crawl: public" to its HTTP headers. This field is
currently set by the peer_private option in the rippled.cfg file.
2015-02-03 12:56:35 -08:00
seelabs
0cc3ef8f90 Add missing include:
* Compile previously failed on Mac with clang
2015-02-03 12:56:32 -08:00
Tom Ritchford
4cbbacc946 Set version to 0.28.0-b3 2015-02-02 17:01:50 -08:00
Vinnie Falco
9a0c71d4a7 NuDB: limit size of mempool (RIPD-787):
Insert now blocks when the size of the memory pool exceeds a predefined
threshold. This solves the problem where sustained insertions cause the
memory pool to grow without bound.
2015-02-02 17:01:19 -08:00
Vinnie Falco
0f1b831de7 Add missing include 2015-02-02 17:01:18 -08:00
Vinnie Falco
37a7a2aacd Fix unsafe iterator dereference in PeerFinder 2015-02-02 17:01:18 -08:00
Tom Ritchford
635b157b11 Fix C++ guards in beast. 2015-02-02 17:01:18 -08:00
Tom Ritchford
c3ae4da83a Fix include guards in rippled. 2015-02-02 17:01:17 -08:00
Tom Ritchford
c3809ece67 New RPC method "version". 2015-02-02 17:01:17 -08:00
Howard Hinnant
bfc436dccd Add metadata to transaction difference logging: RIPD-775 2015-02-02 17:01:16 -08:00
Nik Bougalis
71d6874236 Set version to 0.28.0-b2 2015-01-28 16:34:33 -08:00
Vinnie Falco
9bf1f994ae Remove buffer_view 2015-01-28 16:34:33 -08:00
Vinnie Falco
bb4127a6fb Refactor Serializer and SerializerIterator interfaces:
* Remove unused members
* SerialIter holds only a pointer and offset now
* Use free functions for some Serializer members
* Use SerialIter in some places instead of Serializer
2015-01-28 16:34:33 -08:00
Edward Hennis
a691632995 Support a "--noserver" command line option in tests:
* Run npm/integration tests without launching rippled, using a
  running instance of rippled (possibly in a debugger) instead.
* Works for "npm test" and "mocha"
2015-01-28 16:34:33 -08:00
Miguel Portilla
5d6ea3d75f Combine history_ledger_index and online_delete (RIPD-774) 2015-01-28 16:34:33 -08:00
Mark Travis
43873b1b2c Initialize canDelete_ properly in the constructor. 2015-01-28 16:34:33 -08:00
Mark Travis
9430f3665b Speed up access to ledger index value that can be deleted. 2015-01-28 16:34:33 -08:00
Vinnie Falco
f3c1f63444 Remove LevelDB and HyperLevelDB backends:
The LevelDB and HyperLevelDB are removed from the backend choices. Neither
were recommended for production environments. As RocksDB is not available
on Windows platforms yet, the recommended backend choice for Windows is NuDB.
2015-01-28 13:43:00 -08:00
Nik Bougalis
b5c7232d6f Set version to 0.28.0-b1 2015-01-27 18:21:54 -08:00
Edward Hennis
2f3677d593 Change timing on "sequence realignment" test. 2015-01-27 18:21:54 -08:00
Howard Hinnant
1e0efaffe8 Add missing includes. 2015-01-27 18:21:54 -08:00
Vinnie Falco
fc79754750 Remove unused SHAMap fields 2015-01-26 19:25:38 -08:00
Miguel Portilla
0e4de42be8 Add RPC metrics (RIPD-705)
Add metrics to record the number of RPC requests received. Record the number of
node store fetches performed per request. Additionally record the byte size of
each request response and measure the response time of each request in
milliseconds.

A new class, ScopedMetrics, uses the Boost Thead Local Storage mechanism to
efficiently record NodeStore metrics within the same thread.
2015-01-26 19:25:38 -08:00
Scott Determan
4e389127b5 Use microsecond granularity for sqlite lock backoff algorithm:
When sql tries to acquire a lock that is already held, it sleeps for some
microseconds using the usleep function and then try to acquire the lock
again. However, if the HAVE_USLEEP macro is not defined then the sleep
function will be used.

This fix will define HAVE_USLEEP even when it is not already defined by
the system. Although some Linux distros may not define HAVE_USLEEP,
all supported versions provide usleep. If the system does not actually
have a usleep function, then the compiler will flag the error.
2015-01-26 19:13:40 -08:00
Nik Bougalis
47593730d6 Modernize code:
* Clean STBase-derived class creation interfaces
* Annotate overriden STBase virtual functions
* Optimize path deserialization
* Prefer range-based for
* Prefer std::unique_ptr
* Remove BOOST_FOREACH
2015-01-26 19:13:40 -08:00
Tom Ritchford
e742da73bd Simplify lookupLedger(). 2015-01-26 19:13:40 -08:00
Vinnie Falco
890bf3cce1 Add PeerFinder Logic backoff unit test 2015-01-26 19:13:40 -08:00
Nik Bougalis
60eb312e3b Fix order of construction of Application members 2015-01-26 19:13:40 -08:00
Tom Ritchford
06207da185 Move Context.h up into rpc/. 2015-01-26 19:13:40 -08:00
Nicholas Dudfield
4dc2cf8a6b Update tests to support latest ripple-lib:
* Update ripple-lib api usage
* Use latest npm ripple-lib
  * Tested with bignumber.js branch and tip of develop
* Use new version of coffee-script
  * Better source maps
* Update mocha
* Add assert-diff for better error reporting
* Add rconsole, enabled via USE_RCONSOLE env var
  * For use with manual installation only
2015-01-26 19:13:40 -08:00
Scott Determan
44450bf644 Enable Amendments from config file or static data (RIPD-746):
* The rippled.cfg file has a new section called "amendments"

* Each line in this section contains two white-space separated items
** The first item is the ID of the amendment (a 256-bit hash)
** The second item is the friendly name

* Replaces config section name macros with variables

* Make addKnown arguments safer

* Added lock to addKnown
2015-01-26 19:13:02 -08:00
Nik Bougalis
312aec79ca Remove WalletAdd (RIPD-725) 2015-01-26 12:39:13 -08:00
Nik Bougalis
a8578c73f8 Remove support for deprecated PreviousTxnID field (RIPD-710):
The PreviousTxnID field has been deprecated and should not be used for
transactions that use the field will now be rejected.

The AccountTxnID feature should be used instead by enabling transaction
tracking and specifying a transaction ID at submission. More details
are available at: https://ripple.com/build/transactions/#accounttxnid
2015-01-26 12:39:13 -08:00
Miguel Portilla
c522ffa6db Eliminate temREDUNDANT_SEND_MAX (RIPD-590):
The rules for when a SendMax is redundant are complicated. It is easier to
always allow a SendMax and eliminate temREDUNDANT_SEND_MAX.
2015-01-26 12:39:13 -08:00
Nik Bougalis
93b7599b1c Fix missing 'else' when handling sfMessageKey:
When clearing out a message key the transactor would incorrectly
create an empty `sfMessageKey` field instead of simply deleting
the field.

Clarify logic by reordering checks.
2015-01-26 12:39:13 -08:00
Nik Bougalis
3ccbd7c9b2 Finalize autobridging implementation (RIPD-179):
Autobridging uses XRP as a natural bridge currency to allow IOU-to-IOU orders
to be satisfied not only from the direct IOU-to-IOU books but also over the
combined IOU-to-XRP and XRP-to-IOU books.

This commit addresses the following issues:

* RIPD-486: Refactoring the taker into a unit-testable architecture
* RIPD-659: Asset-aware offer crossing
* RIPD-491: Unit tests for IOU to XRP, XRP to IOU and IOU to IOU
* RIPD-441: Handle case when autobridging over same owner offers
* RIPD-665: Handle case when autobridging over own offers
* RIPD-273: Groom order books while crossing
2015-01-26 12:39:13 -08:00
Nik Bougalis
385a87db31 Claim a fee when a required destination tag is not specified (RIPD-574) 2015-01-26 12:39:12 -08:00
Nik Bougalis
5530353eef Add simplified explicit interfaces to handle XRP and IOU transfers:
The new interfaces take into account the different semantics of XRP, which
do not have an issuer or transfer fees, and IOUs which have issuers and
(optional) transfer fees.

For XRP, the new `LedgerEntrySet::transfer_xrp` will transfer the specified
amount of XRP between from a given source to a given destination.

For IOU, two new functions are introduced:
* `LedgerEntrySet::issue_iou` which transfers the specified amount of an
IOU from the IOU's issuer to an account.
* `LedgerEntrySet::redeem_iou` which transfers the specified amount of an
IOU from an account to the IOU's issuer.

A transfer from user-to-user (e.g. to fill an order during offer crossing)
requires the use of `redeem_iou` followed by `issue_iou`. This helps to
enforce the Ripple invariant that IOUs never flow directly from user to
user, but only through a gateway. Additionally, this  allows for the
explicit calculation and application of transfer fees by varying the
amounts redeemed and issued.

The new interfaces promote type safety since you cannot use the issue
and redeem APIs with XRP or the transfer API with IOU, and the issuer
to be used is implied by the currency being issued or redeemed.
2015-01-26 12:39:12 -08:00
Nik Bougalis
d1193093ef Require the master key when performing certain operations (RIPD-666):
* When disabling the use of the master key; or
* When enabling 'no freeze'.
2015-01-26 12:39:12 -08:00
David Schwartz
b203db27a4 Fix offer->ACCOUNT->offer 2015-01-26 12:39:12 -08:00
JoelKatz
0a3e1af04c When pathfinding, don't output a redundant account node 2015-01-26 12:39:12 -08:00
Vinnie Falco
c6c8e5d70c Set version to 0.27.0 2015-01-26 10:56:11 -08:00
Nik Bougalis
fa354ec8d9 Set version to 0.27.0-b11 2015-01-23 17:37:18 -08:00
Nik Bougalis
d0375f697d Invoke correct deleter 2015-01-23 17:34:30 -08:00
Vinnie Falco
33c8257d25 Set version to 0.27.0-b10 2015-01-21 15:25:11 -08:00
Scott Determan
f389bc33c3 VSProject: Handle tuples in CPPDEFINES:
The VSProject generator now handles tuples in addition to strings and
dicts when converting environment variables such as CPPDEFINES.
2015-01-21 15:20:06 -08:00
Vinnie Falco
4d5dca71ce Squelch Peerfinder fixed connection attempts 2015-01-21 14:59:47 -08:00
Vinnie Falco
a9c44a1b9c Set version to 0.27.0-b9 2015-01-21 14:23:50 -08:00
Vinnie Falco
4144f800a1 Fix PeerImp concurrent access of socket:
The PeerImp::run launch function is now dispatched on the strand to prevent
undefined behavior resulting from concurrent access to the ssl::stream object.
2015-01-21 14:21:43 -08:00
Vinnie Falco
6ef9a81017 Set version to 0.27.0-b8 2015-01-21 14:21:43 -08:00
Vinnie Falco
8c6722f3c5 Remove use of date and time from rocksdb unity build 2015-01-21 14:21:43 -08:00
Vinnie Falco
40e138627b Fixes to Overlay:
* Make ~Peer virtual
* Call close in ConnectAttempt::stop
* Handle nullptr return in new_outbound_slot
* Check gracefulClose_ in read loop
2015-01-21 10:48:32 -08:00
Vinnie Falco
a470dda4e6 Fix Journal::Stream::active to return the correct value 2015-01-21 10:48:32 -08:00
Edward Hennis
b725410623 Option to specify rippled path on command line.
* --rippled=<absolute or relative path>
* Works for "npm test" and "mocha"
* Remove "rippled_path" from config.js to require CLI path.
2015-01-21 10:48:31 -08:00
Miguel Portilla
a9dfb33126 Log abnormal close time offsets (RIPD-572) 2015-01-21 10:48:31 -08:00
Miguel Portilla
8b848770dc Add config "ledger_history_index" functionality (RIPD-559) 2015-01-21 10:48:31 -08:00
Vinnie Falco
94629edb9b Add NuDB backend:
The NuDB database backend is a high performance key/value store presented
as an alternative to RocksDB on Mac and Linux deployments, and the preferred
backend option for Windows deployments. The LevelDB backend is deprecated for
all platforms.

This includes these changes:

* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-21 10:48:30 -08:00
Vinnie Falco
2a3f2ca28d Add NuDB: A Key/Value Store For Decentralized Systems
NuDB is a high performance key/value database optimized for insert-only
workloads, with these features:

* Low memory footprint
* Values are immutable
* Value sizes from 1 2^48 bytes (281TB)
* All keys are the same size
* Performance independent of growth
* Optimized for concurrent fetch
* Key file can be rebuilt if needed
* Inserts are atomic and consistent
* Data file may be iterated, index rebuilt.
* Key and data files may be on different volumes
* Hardened against algorithmic complexity attacks
* Header-only, nothing to build or link
2015-01-21 10:48:30 -08:00
Edward Hennis
8ab1e7d432 Integration test to subscribe to offer books. 2015-01-20 16:45:04 -08:00
Miguel Portilla
b2ba6a0c85 Fix RPC subscribe with multiple books 2015-01-20 16:45:04 -08:00
Tom Ritchford
cca5421aed Fix Subscribe RPC to correctly distinguish bids and asks. 2015-01-20 16:45:04 -08:00
Nik Bougalis
799d9a73e6 Ensure that hash_append will never throw
Conflicts:
	src/beast/beast/net/IPAddress.h
2015-01-20 16:45:03 -08:00
Scott Determan
b0781622b2 Handle nullptr return values to InboundLedgers::findCreate
In normal operation, InboundLedgers::findCreate never returns null, but
during system shutdown, it will return null.

Since this only happens in system shutdown, when findCreate returns null
the calling function stops what it was doing and returns.

During testing, an issue where destroying the application object
and creating a new one caused problems with a static PathTable. This table
is now cleared when re-initialized.
2015-01-20 16:45:03 -08:00
Tom Ritchford
0d0eec6345 Clean up test documentation and a log message. 2015-01-20 16:45:03 -08:00
Nik Bougalis
1af79f7960 Properly validate the configured online delete interval 2015-01-20 16:45:03 -08:00
Vinnie Falco
15b570bbdd Add profile targets for gcc and clang 2015-01-20 16:45:02 -08:00
Tom Ritchford
7aa5599cc2 Remove unused parameter in two lambdas. 2015-01-20 16:45:02 -08:00
JoelKatz
676293ec42 Ensure account_tx queries over and returns correct range 2015-01-20 16:45:02 -08:00
Nik Bougalis
abc4fb81b1 Improve RippleLineCache hashing 2015-01-20 16:45:01 -08:00
Vinnie Falco
53a16f354f Add hardened_hash to basics/:
xxhasher is the default hash function for hardened_hash.
2015-01-20 16:45:01 -08:00
Vinnie Falco
6ab1ecd836 Tidy up container hash functions:
* Add xxhasher
* Move fnv1a, siphash, spookyto hash/
* Move hash_append, uhash to hash/
* Move hash_speed_test to hash/
* Move hash classes to individual header files
* Remove hardened_hash
2015-01-20 16:45:01 -08:00
Vinnie Falco
e7b16e7b47 Add rngfill 2015-01-20 16:45:01 -08:00
Vinnie Falco
14804f81a8 Optimize calls to unit_test::suite::expect:
This changes expect and unexpected to receive the reason text as a
template argument, allowing the std::string conversion of char const*
parameters to take place only if the condition evaluates to false. This
cuts all calls to malloc and free on tests that pass.
2015-01-20 16:45:00 -08:00
Vinnie Falco
9a61b8d77d Declare base_uints with using statements 2015-01-20 16:45:00 -08:00
Vinnie Falco
f42c2763d5 Improve streambuf unit test 2015-01-20 16:45:00 -08:00
Vinnie Falco
98d4e0e1b5 Fix ZeroCopyOutputStream:
Added a destructor that commits the last block of data
if there was no final call to BackUp.
2015-01-20 16:45:00 -08:00
Tom Ritchford
9156633baf Set version to 0.27.0-b7 2015-01-20 17:59:55 -05:00
Tom Ritchford
bcf4f836b4 Use websocketpp_02 namespace. 2015-01-20 17:08:15 -05:00
Vinnie Falco
dbc1d70f99 Set version to 0.27.0-b6 2015-01-20 09:41:27 -08:00
Vinnie Falco
78bc190a85 Merge commit '02855d7fed46d3c1aa1f2cefbcf4a42720575c3f' as 'src/websocketpp' 2015-01-20 09:35:00 -08:00
Vinnie Falco
02855d7fed Squashed 'src/websocketpp/' content from commit 875d420
git-subtree-dir: src/websocketpp
git-subtree-split: 875d420952
2015-01-20 09:35:00 -08:00
Vinnie Falco
6fdd5d32be Rename websocket/ to websocketpp_02 2015-01-20 09:34:54 -08:00
Vinnie Falco
d7f32b105b Set version to 0.27.0-b5 2015-01-13 11:50:58 -08:00
Vinnie Falco
0ac480a0bd Fix extra increment in GenerateRootDeterministicKey 2015-01-13 11:49:59 -08:00
Tom Ritchford
417996de02 Set version to 0.27.0-b4 2015-01-13 11:30:23 -05:00
Tom Ritchford
6c2d60cec2 Prevent RPC handlers from returning non-objects. 2015-01-13 11:30:23 -05:00
Tom Ritchford
743bd6c917 Fix RPC command logrotate to return a Json object. 2015-01-13 11:30:14 -05:00
Edward Hennis
ab61aa41d9 Set version to 0.27.0-b3 2015-01-12 18:00:55 -05:00
Edward Hennis
36396ae29e rippled.cfg [db_node] options for RocksDB
* open_files and compression.
2015-01-12 18:00:54 -05:00
Vinnie Falco
749e083e6e NodeStore improvements:
* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-12 18:00:52 -05:00
Vinnie Falco
67b9cf9e82 Improved support for exceptions in threads spawned by unit tests:
Unit tests that wish to spawn threads for testing concurrency may now do so
by using unit_test::thread as a replacement for std::thread. These threads
propagate unhandled exceptions to the unit test, and work with the abort on
failure feature.
2015-01-12 17:17:09 -05:00
Vinnie Falco
27fb20f3ab Add xor_shift_engine 2015-01-12 17:17:07 -05:00
Josh Juran
1c71b274f0 SConstruct: Add ed25519.c
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
	SConstruct
2015-01-12 12:16:26 -08:00
Vinnie Falco
fcd20b63fe Merge commit '8ec344ac1b6c66d936fa0f7005490e126a434a70' as 'src/ed25519-donna' 2015-01-12 11:27:15 -08:00
Vinnie Falco
8ec344ac1b Squashed 'src/ed25519-donna/' content from commit 04223b0
git-subtree-dir: src/ed25519-donna
git-subtree-split: 04223b04e22f5eff32c6c27e25194d4d984c6f41
2015-01-12 11:27:15 -08:00
Vinnie Falco
df966a9ac6 Set version to 0.27.0-b2 2015-01-05 18:49:18 -08:00
Vinnie Falco
f634666dc6 Make rocksdbquick settings default:
This removes the old default configuration for the "rocksdb" backend and
replaces it with the configuration that was formerly available using
the experimental backend "rocksdbquick".

The new configuration setting improves the performance of the key/value
database by changing the compaction style and tuning the size parameters for
the typical rippled workload. Testing shows a decrease in I/O spikes for both
reading and writing.
2015-01-05 18:49:17 -08:00
Tom Ritchford
e2f9f5d7e5 Fix compilation warnings. 2015-01-05 18:49:17 -08:00
Tom Ritchford
d078b0d143 Extract the git ID into a separate compilation unit. 2015-01-05 18:49:15 -08:00
Nik Bougalis
0ccdea3cd8 Disable Ticket transactions and tests 2015-01-05 14:18:27 -08:00
Vinnie Falco
df54b47cd0 Tidy up includes and add modules to the classic build:
An alternative to the unity build, the classic build compiles each
translation unit individually. This adds more modules to the classic build:

* Remove unity header app.h
* Add missing includes as needed
* Remove obsolete NodeStore backend code
* Add app/, core/, crypto/, json/, net/, overlay/, peerfinder/ to classic build
2015-01-05 13:35:57 -08:00
Vinnie Falco
2e595830b3 Levelize SHAMap:
The SHAMap class is refactored into a separate module where each translation
unit compiles separate without errors. Dependencies on higher level business
logic are removed. SHAMap now depends only on basics, crypto, nodestore,
and protocol:

* Inject NodeStore::Database& to SHAMap
* Move sync filter instances to app/ledger/
* Move shamap to its own module
* Move FullBelowCache to shamap/
* Move private code to shamap/impl/
* Refactor SHAMap treatment of missing node handler
* Inject and use Journal for logging in SHAMap
2015-01-05 11:46:11 -08:00
Vinnie Falco
96fbcc9a5a Refactor NodeStore:
Manager is changed to be a Meyer's singleton, with factories automatically
registering upon construction.
2015-01-05 11:46:11 -08:00
Vinnie Falco
6283801981 Add non-unity build targets:
The SConstruct is modified to provide a new family of targets, ending with
the suffix ".nounity", which compile individual translation units instead of
some of the unity translation units ("classic" builds). Two modules updated
for this treatment are ripple/basics/ and ripple/protocol/, with plans to
update more in the future. A consequence is longer build times in some cases.
A benefit of classic builds is that missing includes can be identified
through compiler errors.
2015-01-05 11:46:11 -08:00
Vinnie Falco
9a3214d46e Normalize files containing unit test code:
Source files are split to place all unit test code into translation
units ending in .test.cpp with no other business logic in the same file,
and in directories named "test".

A new target is added to the SConstruct, invoked by:
    scons count
This prints the total number of source code lines occupied by unit tests,
in rippled specific code and excluding library subtrees.
2015-01-05 11:46:07 -08:00
Vinnie Falco
9eb7c8344f Don't leak track StringPairArray 2015-01-05 11:44:15 -08:00
Vinnie Falco
4140bbb1f7 Set version to 0.27.0-b1 2015-01-05 11:37:01 -08:00
Vinnie Falco
ea44497136 Fix msvc ICE on initializer-list 2015-01-05 11:37:00 -08:00
Nik Bougalis
07737c6e5b Add 'delivered_amount' to Transaction JSON (RIPD-643):
The synthetic field 'delivered_amount' can be used to determine the exact
amount delivered by a Payment without having to check the DeliveredAmount
field, if present, or the Amount field otherwise.

The field is only returned when metadata is available and the data is not
returned in binary format.
2014-12-31 01:55:10 -08:00
JoelKatz
98d5eefc86 Pathfinding bugfixes (RIPD-735):
* Fix specifying paths and search level for ripple_path_find
* Don't modify the pathfinder, it has issuer-neutral paths.
* Handle previous paths correctly
* Compare paths correctly
2014-12-31 01:55:10 -08:00
JoelKatz
4f2d93bb65 Avoid processing transactions if we need a network ledger
Not processing tranasctions without a network ledger makes
initial network synchronization faster.
2014-12-31 01:55:10 -08:00
Edward Hennis
a5df3f1747 Support a "no_server" flag in test config.
* Will use a running instance of rippled (possibly in a debugger).
* Modify all tests to respect the server_default value.
* Fail test if new account already exists and has a balance.
* README.md with instructions for advanced test debugging, particularly using no_server.
2014-12-31 01:55:10 -08:00
Howard Hinnant
7f5f73887d Fix undefined behavior 2014-12-31 01:55:10 -08:00
Nik Bougalis
91ce7807b9 Remove legacy LoadTypes (RIPD-365) 2014-12-31 01:55:10 -08:00
Nik Bougalis
d26fae9875 Reduce Beast dependencies by leveraging C++11 features:
* Remove beast::Atomic (RIPD-728):
  * Use std-provided alternatives
  * Eliminate atomic variables where possible

* Cleanup beast::Thread interface:
  * Use std::string instead of beast::String
  * Remove unused functions and parameters

* Remove unused code:
  * beast::ThreadLocalValue
  * beast::ServiceQueue
2014-12-31 01:55:10 -08:00
Nik Bougalis
60bdc79ec4 Remove unused sitefiles module 2014-12-30 12:33:41 -08:00
Tom Ritchford
253ddf2998 Split off CheckLibraryVersions.test.cpp. 2014-12-30 12:33:41 -08:00
Nik Bougalis
9fa15b390a Always initialize LedgerHandler options field 2014-12-29 11:21:19 -08:00
Josh Juran
e7d6fe6c8b Cull duplicate/unused code in RippleAddress:
Deduplicate a call to GeneratePublicDeterministicKey().
Remove unused member functions.
2014-12-29 11:21:19 -08:00
Tom Ritchford
9650b1aa70 New ripple::TestSuite with method expectEquals(). 2014-12-29 11:21:19 -08:00
Howard Hinnant
eafa6f960f API for improved Unit Testing (RIPD-432):
* Added new test APIs allowing easy ways to create ledgers, apply
  transactions to them, close and advance them.

* Moved Ledger tests from Ledger.cpp to Ledger.test.cpp.

* Changed several TransactionEngine log priorities from lsINFO to lsDEBUG to
  reduce unnecessary verbosity in the log messages while running these tests.

* Moved LedgerConsensus:applyTransactions from a private member function to a
  free function so that it could be accessed externally, and without having to
  reference a LedgerConsensus object.  This was done to facilitate the new
  testing API.
2014-12-29 11:21:19 -08:00
Yana
c62ccf4870 Update README.md (RIPD-601) 2014-12-29 11:21:19 -08:00
Vinnie Falco
ef34439a79 Set version to 0.26.5-rc1 2014-12-22 15:20:03 -08:00
Nik Bougalis
b328ec2462 Prevent passing of non-POD types to POD-only interfaces:
This tidies up the code that produces random numbers to conform
to programming best practices and reduce dependencies.

* Use std::random_device instead of platform-specific code
* Remove RandomNumbers class and use free functions instead
2014-12-22 15:19:48 -08:00
Vinnie Falco
60f27178b8 Levelization, improve structure of source files:
Source files are moved between modules, includes changed and added,
and some code rewritten, with the goal of reducing cross-module dependencies
and eliminating cycles in the dependency graph of classes.

* Remove RippleAddress dependency in CKey_test
* ByteOrder.h, Blob.h, and strHex.h are moved to basics/. This makes
  the basics/ module fully independent of other ripple sources.
* types/ is merged into protocol/. The protocol module now contains
  all primitive types specific to the Ripple protocol.
* Move ErrorCodes to protocol/
* Move base_uint to basics/
* Move Base58 to crypto/
* Remove dependence on Serializer in GenerateDeterministicKey
* Eliminate unity header json.h
* Remove obsolete unity headers
* Remove unnecessary includes
2014-12-22 10:23:49 -08:00
Vinnie Falco
e3fbb83ad0 Tidy up usage of std::begin, std::end 2014-12-19 11:55:43 -08:00
Nik Bougalis
28b70a7b9a Remove 'Proof of Work' code 2014-12-19 11:00:29 -08:00
Nicholas Dudfield
dcdc341d0f Add appveyor 2014-12-19 11:00:29 -08:00
Tom Ritchford
fce77c9372 Configuration for yielding RPC server. 2014-12-19 11:00:28 -08:00
Tom Ritchford
a360c481c2 Refactor out a version of lookupLedger returning Status. 2014-12-19 11:00:28 -08:00
Tom Ritchford
c72db5fa5f Refactor away RPCHandler::doRpcCommand 2014-12-19 11:00:28 -08:00
Tom Ritchford
fc9a23d6d4 Send output incrementally in ServerHandlerImp. 2014-12-19 11:00:27 -08:00
Tom Ritchford
167f4666e2 New generic Ledger RPC handler. 2014-12-19 11:00:27 -08:00
Tom Ritchford
1cbcc7be21 Allow the Ledger to generically output to both Json models. 2014-12-19 11:00:27 -08:00
Tom Ritchford
8053598069 Better interoperation between Json::Value and JsonObject.
* Generic functions to add entries to both object models.
* Add Json::Value into JsonObjects.
* Write Json::Value to string incrementally.
* Get rid of ripple::RPC::New namespace
2014-12-19 11:00:26 -08:00
Tom Ritchford
7cfac1a91a Wrap Output in a coroutine that periodically yields. 2014-12-19 11:00:26 -08:00
Tom Ritchford
192cdd028e Change Output to be a generic std::function. 2014-12-19 11:00:26 -08:00
Tom Ritchford
029c143922 Add a comment to ledger/Ledger.h. 2014-12-19 11:00:26 -08:00
Tom Ritchford
00298cc68c Simplify LedgerData.cpp. 2014-12-19 11:00:25 -08:00
Tom Ritchford
d9c7db51af Make three ErrorCode functions generic. 2014-12-19 11:00:25 -08:00
Vinnie Falco
f12b15d22b Fix logic in HTTP/S server:
These bugs do not affect production code since callers do not invoke
`write` multiple times, but these would become a problem in the future.

* Access to Peer::write_queue_ is synchronized correctly.
* Remove unsafe access to deleted container element.
2014-12-19 11:00:25 -08:00
Vinnie Falco
409b8bac00 Remove unused and obsolete Ripple identifiers and tidy up:
These identifiers were part of a failed set of classes to replace
the functionality combined into RippleAddress. They are not used
and therefore can be removed.

* Remove RippleAccountPrivateKey
* Remove RippleAccountPublicKey
* Remove RippleAccountID
* Remove RipplePrivateKey
* Remove RipplePublicKeyHash
* Remove RippleLedgerHash
* Remove unused withCheck argument
* Remove CryptoIdentifier
* Remove IdentifierStorage
* Remove IdentifierType
* Remove SimpleIdentifier
* Add missing include
2014-12-19 11:00:24 -08:00
Vinnie Falco
28b09bde4b Simplify RipplePublicKey:
This implements the bare minimum necessary to store a 33 byte public
key and use it in ordered containers. It is an efficient and well
defined alternative to RippleAddress when the caller only needs
a node public key.
2014-12-19 11:00:24 -08:00
Vinnie Falco
2f6af906f4 Validators work (RIPD-703):
This replaces the experimental validators module with foundational
code to implement a new system for tracking validators, validations and
the UNL. The code is turned off by default, in BeastConfig.h

* Remove obsolete public Manager interfaces
* Remove obsolete database methods
* Remove obsolete ChosenList concept
* Remove obsolete code
* Add missing includes
* Tidy up STValidation.h
* Move factory function to Validators::make_Manager
* Add Connection object for tracking STValidations
2014-12-19 11:00:23 -08:00
Vinnie Falco
628e3ac1eb Add waitable_executor 2014-12-18 10:26:55 -08:00
Josh Juran
fbf5785e35 Combine STTx::checkSign overloads:
Callers don't need to specify the signing key -- they're just retrieving
the key from the SerializedTransaction and then passing it back.

This simplifies Ed25519 implementation.
2014-12-12 20:14:02 -08:00
Nicholas Dudfield
eeea2b1ff8 Use ppa:afrank/boost 1.57 for Travis 2014-12-12 20:14:02 -08:00
Vinnie Falco
32062e439f Split peer connect logic to another class (RIPD-711):
All of the logic for establishing an outbound peer connection including
the initial HTTP handshake exchange is moved into a separate class. This
allows PeerImp to have a strong invariant: All PeerImp objects that exist
represent active peer connections that have already gone through the
handshake process.
2014-12-12 20:14:02 -08:00
Vinnie Falco
930a0beaf1 Add ZeroCopyOutputStream and tidy up 2014-12-12 20:14:02 -08:00
Nik Bougalis
4a49fefdd9 Various cleanups:
* Replace SYSTEM_NAME and other macros with C++ constructs
* Remove RIPPLE_ARRAYSIZE and use std::extent or ranged for loops
* Remove old-style, unused offer crossing unit test
* Make STAmount::saFromRate free and remove default argument
2014-12-12 20:14:02 -08:00
Nik Bougalis
8e792855e0 Do not use path if path expansion fails 2014-12-10 16:55:06 -08:00
Tom Ritchford
69f5c6987a Whitespace: clean WebSockets to 80 columns. 2014-12-10 16:55:06 -08:00
Nik Bougalis
85fc9e4ecf Revert e4c9822d78 "Enable processor-specific optimizations when available:" 2014-12-08 14:54:03 -08:00
Mark Travis
d5c3f0c9cf Stability bugfixes for online delete SHAMapStore:
The correct ledger age is necessary for checking health
status, and the previous behavior caused the online deletion process to
abort if the process took too long.

The tuning parameter added and the parameter whose default was modified both
minimize impact of SQL DELETE operations by decreasing the default batch size
for deletes and for increasing the backoff period between deletion batches.
These parameters decrease contention for the SQLite and I/O with the trade-off
of longer processing time for online delete. Online-delete is not a
time-critical function, so a little slowness in wall-clock time is not harmful.
2014-12-08 14:54:03 -08:00
JoelKatz
a48120e675 Fix incorrect source issuer for XRP source 2014-12-08 14:54:03 -08:00
Nik Bougalis
36f8e4f2ad Improve hex conversion & parsing routines 2014-12-08 14:54:03 -08:00
David Schwartz
1084a39a45 Improve the humanAccountID cache (RIPD-693)
Profiling indicated some performance issues coming from the
cache of 160-bit account IDs to base58 format. This replaces
the single cache with two caches and rotates out old
entries.
2014-12-08 14:54:03 -08:00
Tom Ritchford
86df482842 Make sure that handlers always return Json::objectValue. 2014-12-01 17:16:24 -05:00
Tom Ritchford
b0d47ebcc6 Use better base64 handling in ServerHandlerImp. 2014-12-01 17:15:23 -05:00
Tom Ritchford
fffdf1dfba Make beast::detail::chunk_encoded_buffers::to_hex() static 2014-12-01 11:12:59 -05:00
Tom Ritchford
3273ed2616 Remove unused BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES. 2014-12-01 10:56:03 -05:00
Vinnie Falco
aa7b0a31b0 Refactor protocol message parsing:
This replaces the stateful class parser with a stateless free function.
The protocol buffer message is parsed using a ZeroCopyInputStream.

* Invoke method is now a free function.
* Protocol handler doesn't need to derive from an abstract interface
* Only up to one message is processed at a time by the invoker.
* Remove error_code return from the handler's message processing functions.
* Add ZeroCopyInputStream implementation that wraps a BufferSequence.
* Free function parses up to one protocol message and calls the handler.
* Message type and size can be calculated from an iterator
  range or a buffer sequence.
2014-11-26 12:23:21 -08:00
Vinnie Falco
fb0d44d403 Use cluster state in Slot instead of PeerImp 2014-11-26 12:23:10 -08:00
Vinnie Falco
cd8ec89cbb Use injections from OverlayImpl in PeerImp 2014-11-26 12:23:02 -08:00
Vinnie Falco
252f271dc5 Fixes to beast::asio::streambuf:
* Fix to_string conversion
* Fix assert on debug invariant checks
* Fix the treatment of the output position when the entire output is committed.
* Add unit test
2014-11-26 12:22:55 -08:00
Vinnie Falco
62d400c3a9 Move the call to cancel_timer to the right place 2014-11-26 12:22:46 -08:00
Scott Schurr
f9aa3e0da5 Add more unit tests to rpc/impl/TransactionSign (RIPD-480):
By adding a mock it is possible to test the transactionSign
function without interacting with the ledger.  This is the
smallest change I could come up with that allows transactionSign
to be unit tested.

The unit tests are white boxed.  Each test case is a result
of examining the code and identifying behavior associated with
different JSON fields.  That means the tests are not based on
requirements, they are based on observed behavior.
2014-11-26 12:07:44 -08:00
Vinnie Falco
685fe5b0fb Don't call std::exit on clean exit 2014-11-25 19:19:56 -08:00
Vinnie Falco
5180e71a0d Remove unused chrono::time_point stream conversions 2014-11-25 19:19:56 -08:00
Vinnie Falco
55637f7508 Template abstract_clock on Clock:
The abstract_clock is now templated on a type meeting the requirements of
the Clock concept. It inherits the nested types of the Clock on which it
is based. This resolves a problem with the original design which broke the
type-safety of time_point from different abstract clocks.
2014-11-25 19:19:56 -08:00
Nicholas Dudfield
7d72dfe0be Updated freeze tests:
* Always run freeze tests (and  enforcement tests)
* book_offers filtering tests are broken
2014-11-25 11:46:34 -08:00
Mark Travis
02529a0fc2 SHAMapStore Online Delete (RIPD-415):
Makes rippled configurable to support deletion of all data in its key-value
store (nodestore) and ledger and transaction SQLite databases based on
validated ledger sequence numbers. All records from a specified ledger
and forward shall remain available in the key-value store and SQLite, and
all data prior to that specific ledger may be deleted.

Additionally, the administrator may require that an RPC command be
executed to enable deletion. This is to align data deletion with local
policy.
2014-11-25 11:44:02 -08:00
JoelKatz
b44974677e Cleanup some stray formatting left in logs 2014-11-21 17:13:13 -08:00
Vinnie Falco
d4fd5e4fce HTTP Handshaking for Peers on Universal Port (RIPD-446):
This introduces a considerable change in the way that peers handshake. Instead
of sending the TMHello protocol message, the peer making the connection (client
role) sends an HTTP Upgrade request along with some special headers. The peer
acting in the server role sends an HTTP response completing the upgrade and
transition to RTXP (Ripple Transaction Protocol, a.k.a. peer protocol). If the
server has no available slots, then it sends a 503 Service Unavailable HTTP
response with a JSON content-body containing IP addresses of other servers to
try. The information that was previously contained in the TMHello message is
now communicated in the HTTP request and HTTP response including the secure
cookie to prevent man in the middle attacks. This information is documented
in the overlay README.md file.

To prevent disruption on the network, the handshake feature is rolled out in
two parts. This is part 1, where new servents acting in the client role will
send the old style TMHello handshake, and new servents acting in the server
role can automatically detect and accept both the old style TMHello handshake,
or the HTTP request accordingly. This detection happens in the Server module,
which supports the universal port. An experimental .cfg setting allows clients
to instead send HTTP handshakes when establishing peer connections. When this
code has reached a significant fraction of the network, these clients will be
able to establish a connection to the Ripple network using HTTP handshakes.

These changes clean up the handling of the socket for peers. It fixes a long
standing bug in the graceful close sequence, where remaining data such as the
IP addresses of other servers to try, did not get sent. Redundant state
variables for the peer are removed and the treatment of completion handlers is
streamlined. The treatment of SSL short reads and secure shutdown is also fixed.

Logging for the peers in the overlay module are divided into two partitions:
"Peer" and "Protocol". The Peer partition records activity taking place on the
socket while the Protocol partition informs about RTXP specific actions such as
transaction relay, fetch packs, and consensus rounds. The severity on the log
partitions may be adjusted independently to diagnose problems. Every log
message for peers is prefixed with a small, unique integer id in brackets,
to accurately associate log messages with peers.

HTTP handshaking is the first step in implementing the Hub and Spoke feature,
which transforms the network from a homogeneous network where all peers are
the same, into a structured network where peers with above average capabilities
in their ability to process ledgers and transactions self-assemble to form a
backbone of high powered machines which in turn serve a much larger number of
'leaves' with lower capacities with a goal to improve the number of
transactions that may be retired over time.
2014-11-21 16:47:12 -08:00
Vinnie Falco
30123eaa4a Add WrappedSink:
This class puts a configured string prefix in front of
each line of Journal output.
2014-11-21 16:46:57 -08:00
Nik Bougalis
454ec97d51 Replace custom exceptions with std::runtime_error 2014-11-21 13:15:41 -08:00
Vinnie Falco
c2ac331e78 Fix unit_test suite matching with full names 2014-11-21 12:59:32 -08:00
Nik Bougalis
be4a35af11 Clarify SetAccount logic and clean up existing code 2014-11-21 12:59:32 -08:00
Tom Ritchford
445b29ad0d Fix RPC handlers to use the results of lookupLedger. 2014-11-21 12:59:32 -08:00
Vinnie Falco
64d0f7fffd Fix DecayingSample treatment of the window 2014-11-21 12:59:32 -08:00
Nik Bougalis
baf0d09455 Simplify the Beast fatal error reporting framework:
* Reduce interface to a single function which reports error details
* Remove unused functions
2014-11-21 12:59:32 -08:00
Vinnie Falco
08a81a0ab9 Tidy up the structure of sources in protocol/:
Split out and rename STValidation
Split out and rename STBlob
Split out and rename STAccount
Split out STPathSet
Split STVector256 and move UintTypes to protocol/
Rename to STBase
Rename to STLedgerEntry
Rename to SOTemplate
Rename to STTx
Remove obsolete AgedHistory
Remove types.h and add missing includes
Remove unnecessary includes in app.h
Remove unnecessary includes in app.h
Remove include app.h from app1.cpp
2014-11-20 20:15:29 -08:00
Nik Bougalis
31110c7fd9 Cleanup ripple::Ledger:
* Convert static member functions to free functions
* Adopt consistent naming convention
* De-inline code
2014-11-20 20:15:29 -08:00
Vinnie Falco
0e1dd92d9b Fix case where slot==nullptr in Overlay:
This changes the Overlay to correctly handle the case when nullptr is
returned by PeerFinder new_inbound_slot on a detected self-connection.
2014-11-20 20:15:29 -08:00
Vinnie Falco
a3204a4df7 Add http::chunk_encode:
This transforms a ConstBufferSequence into a new ConstBufferSequence whose
data is encoded according to the Content transfer encoding rules of RFC2616.
The implementation does not copy any memory.
2014-11-20 20:15:29 -08:00
Donovan Hide
2288ab48b9 Use asio signal handling in Application (RIPD-140):
* Use signal_set as cross platform way of handling SIGINT
* Remove polling on main thread for shutdown.
* Add extra logging for received signal.
* Clean up exit handling on error in setup routines.
* Reuse isStopped() from Stoppable for status (could be isStopping() instead).
* Ctrl-C should now work for standalone mode as well on Windows.

Also small fixes to Resolver:
* Add Resolver prefix to logging.
* Fix AsyncObject::removeReference() logic.
* Fix work remaining logic.
2014-11-20 20:15:29 -08:00
mDuo13
670401884c Improve the human-readable description of the tesSUCCESS code:
Transactions that return tesSUCCESS have only been accepted and
propagated on the Ripple network and should not be considered
final until they have been included in a validated ledger.
2014-11-20 20:14:04 -08:00
Yana
37181c341e Changed doc/rippled-example.cfg to specify default for ssl_verify 2014-11-14 11:19:42 -08:00
wltsmrz
be7e677448 Update integration tests for changes to ripple-lib account request API:
Account requests expect an object as first argument
2014-11-14 11:10:12 -08:00
Josh Juran
b2eeb49a45 Clean up CKey and RippleAddress (RIPD-672)
* Remove CKey dependency on RippleAddress
* Create RAII ec_key wrapper that hides EC_KEY and other OpenSSL details
* Move CKey member logic into free functions
* Delete CKey class
* Rename units that are no longer CKey-related
* Delete code that was unused
2014-11-14 11:10:12 -08:00
Vinnie Falco
9aa040d917 Accept generic arguments in ci_equal 2014-11-14 11:10:11 -08:00
Vinnie Falco
c2043a223b Tidy up split_commas function and use it in Server
Conflicts:
	src/ripple/server/impl/ServerHandlerImp.cpp
2014-11-14 11:10:11 -08:00
Vinnie Falco
f24e859f17 Construct Server after Overlay and WSDoors:
When the ServerHandler is constructed before the Overlay, an incoming
connection received after the server's listening ports have been opened
but before the Overlay object has been created causes a crash.
2014-11-14 11:10:11 -08:00
Vinnie Falco
737b33f9d1 Merge branch 'release' into develop 2014-11-14 10:56:45 -08:00
David Schwartz
00791d2151 Set version to 0.26.4-sp3 2014-11-11 16:33:52 -08:00
David Schwartz
b141598f9b Fix bugs in pathfinding with XRP as the source currency 2014-11-11 16:27:39 -08:00
Tom Ritchford
d1618d79b0 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-11 16:27:03 -08:00
Tom Ritchford
00c84dfe5c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.
2014-11-11 16:26:38 -08:00
Vinnie Falco
95f31b98a8 Set version to 0.26.4-sp2 2014-11-11 14:22:37 -08:00
Miguel Portilla
10d74ed100 Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct ledger info. account_offers, account_lines and book_offers allow admins unlimited size on the limit param. Specifying a negative value on limit clamps to the minimum value allowed. Incorrect types for limit are correctly reported in the result.
2014-11-11 14:21:49 -08:00
Vinnie Falco
8a7f612d5b Revert pathfinding changes:
* 5e7c527 Revert "Fix account_lines, account_offers and book_offers result (RIPD-682):"
* b3417ca Revert "Fix pathfinding with multiple issuers for one currency (RIPD-618)."
* 00db7f5 Revert "Clean up Pathfinder."
2014-11-11 14:21:40 -08:00
Tom Ritchford
0829ee9234 Add missing header needed for boost 1.57 compatibility. 2014-11-10 23:23:53 -05:00
Nik Bougalis
b22e33444b Make Stoppable unit tests manual 2014-11-10 23:23:53 -05:00
David Schwartz
d115a12cbe Remove dead TxQueue code 2014-11-10 23:23:53 -05:00
Nik Bougalis
b7b744de94 Remove sole use of beast::MurmurHash 2014-11-10 15:00:20 -08:00
Nik Bougalis
68e46e406a Remove MurmurHash from Beast 2014-11-10 14:00:54 -08:00
Tom Ritchford
329a969761 Remove unused RPCServer. 2014-11-10 12:53:21 -08:00
Vinnie Falco
30170bc394 Add short_read manual unit test:
This manual unit test explores the outcomes of shutting down
SSL stream connections at various point during a session.
2014-11-10 12:52:57 -08:00
Vinnie Falco
f193302e15 Add WrappedSink 2014-11-10 12:52:57 -08:00
Vinnie Falco
7c4870d641 Add operator<< for basic_streambuf 2014-11-10 12:52:43 -08:00
Vinnie Falco
8b84a76d5d Make ci_equal a function 2014-11-10 12:52:42 -08:00
Vinnie Falco
a4cd761372 Add rfc2616::parse_csv 2014-11-10 12:52:42 -08:00
Miguel Portilla
63d2cfd6ba Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct
ledger info. account_offers, account_lines and book_offers allow admins
unlimited size on the limit param. Specifying a negative value on limit clamps
to the minimum value allowed. Incorrect types for limit are correctly reported
in the result.
2014-11-10 12:46:36 -08:00
Vinnie Falco
fbffe2367e Fix weak_fn unit test. 2014-11-09 20:27:05 -08:00
Vinnie Falco
e442a2846d Overlay improvements and bug fixes:
PeerImp::detach had a default argument graceful=true which did not
correctly close the socket and cause the Overlay to often hang on exit.
The logging for Overlay and Peers has been reworked. All the socket activity
is logged to Peers while protocol activity goes to Protocol. Every log line
is prefixed by a small integer ID unique to the connection.
* Removed graceful PeerImp::detach option
* Peer and Protocol log message handle respective types of logging
* Log messages prefixed with peer unique integer
* Prevent call to timer ancel from throwing an exception
2014-11-08 14:39:46 -08:00
Vinnie Falco
f6985586ea Better logging when opening Server ports. 2014-11-08 14:36:45 -08:00
Vinnie Falco
2bae5b0959 Throw if rippled.cfg is missing a [server] section 2014-11-08 14:36:45 -08:00
Vinnie Falco
1e58809fcc Remove obsolete get_pointer 2014-11-08 14:36:44 -08:00
Vinnie Falco
6b1d213cc2 Add weak_fn 2014-11-08 14:36:44 -08:00
David Schwartz
42bec13a83 Add missing include needed for std::bad_cast in LexicalCast.h 2014-11-07 15:23:43 -08:00
Vinnie Falco
4415a179b3 Update freeze test for moved TxFlags.h 2014-11-07 14:12:43 -08:00
Vinnie Falco
5d42604efd Refactor the structure of source files:
* New src/ripple/crypto and src/ripple/protocol directories
* Merged src/ripple/common into src/ripple/basics
* Move resource/api files up a level
* Add headers for "include what you use"
* Normalized include guards
* Renamed to JsonFields.h
* Remove obsolete files
* Remove net.h unity header
* Remove resource.h unity header
* Removed some deprecated unity includes
2014-11-07 13:40:43 -08:00
Vinnie Falco
b134b7d3f6 Add missing includes. 2014-11-07 12:24:02 -08:00
Vinnie Falco
788219fe05 Adjust SSL context generation for Server:
The creation of self-signed certificates slows down the command
line client when launched repeatedly during unit test.
* Contexts are no longer generated for the command line client
* A port with no secure protocols generates an empty context
2014-11-07 06:13:56 -08:00
Tom Ritchford
9a7f66cfe9 Fix compilation errors in RPC/RipplePathFind.cpp 2014-11-06 21:58:13 -05:00
Tom Ritchford
daa4d16e61 Remove unused isXRP(Issue) function. 2014-11-06 20:17:13 -05:00
Tom Ritchford
cf05f87795 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-06 20:14:01 -05:00
Tom Ritchford
c2f2f83b7c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.

Conflicts:
	src/ripple/rpc/handlers/RipplePathFind.cpp
2014-11-06 16:58:10 -08:00
Tom Ritchford
b30b2a523f Fix public member names of RPC::Context.
Conflicts:
	src/ripple/rpc/handlers/AccountTx.cpp
	src/ripple/rpc/handlers/AccountTxOld.cpp
	src/ripple/rpc/handlers/Ledger.cpp
	src/ripple/rpc/handlers/LedgerData.cpp
	src/ripple/rpc/handlers/RipplePathFind.cpp
	src/ripple/rpc/handlers/ServerInfo.cpp
	src/ripple/rpc/handlers/ServerState.cpp
	src/ripple/rpc/handlers/Submit.cpp
	src/ripple/rpc/handlers/Subscribe.cpp
	src/ripple/rpc/handlers/TxHistory.cpp
	src/ripple/rpc/handlers/Unsubscribe.cpp
	src/ripple/rpc/impl/Context.h
2014-11-06 16:55:20 -08:00
Nicholas Dudfield
150a3810a8 Update npm test rippled.cfg to use [server]:
The test now generates a configuration file with the new
configuration sections define by the Universal Port feature.
2014-11-06 16:10:00 -08:00
Vinnie Falco
ac0eaa912b Universal Port (RIPD-160):
This changes the behavior and configuration specification of the listening
ports that rippled uses to accept incoming connections for the supported
protocols: peer (Peer Protocol), http (JSON-RPC over HTTP), https (JSON-RPC)
over HTTPS, ws (Websockets Clients), and wss (Secure Websockets Clients).
Each listening port is now capable of handshaking in multiple protocols
specified in the configuration file (subject to some restrictions). Each
port can be configured to provide its own SSL certificate, or to use a
self-signed certificate. Ports can be configured to share settings, this
allows multiple ports to use the same certificate or values. The list of
ports is dynamic, administrators can open as few or as many ports as they
like. Authentication settings such as user/password or admin user/admin
password (for administrative commands on RPC or Websockets interfaces) can
also be specified per-port.

As the configuration file has changed significantly, administrators will
need to update their ripple.cfg files and carefully review the documentation
and new settings.

Changes:

* rippled-example.cfg updated with documentation and new example settings:
  All obsolete websocket, rpc, and peer configuration sections have been
  removed, the documentation updated, and a new documented set of example
  settings added.

* HTTP::Writer abstraction for sending HTTP server requests and responses
* HTTP::Handler handler improvements to support Universal Port
* HTTP::Handler handler supports legacy Peer protocol handshakes
* HTTP::Port uses shared_ptr<boost::asio::ssl::context>
* HTTP::PeerImp and Overlay use ssl_bundle to support Universal Port
* New JsonWriter to stream message and body through HTTP server
* ServerHandler refactored to support Universal Port and legacy peers
* ServerHandler Setup struct updated for Universal Port
* Refactor some PeerFinder members
* WSDoor and Websocket code stores and uses the HTTP::Port configuration
* Websocket autotls class receives the current secure/plain SSL setting
* Remove PeerDoor and obsolete Overlay peer accept code
* Remove obsolete RPCDoor and synchronous RPC handling code
* Remove other obsolete classes, types, and files
* Command line tool uses ServerHandler Setup for port and authorization info
* Fix handling of admin_user, admin_password in administrative commands
* Fix adminRole to check credentials for Universal Port
* Updated Overlay README.md

* Overlay sends IP:port redirects on HTTP Upgrade peer connection requests:
  Incoming peers who handshake using the HTTP Upgrade mechanism don't get
  a slot, and always get HTTP Status 503 redirect containing a JSON
  content-body with a set of alternate IP and port addresses to try, learned
  from PeerFinder. A future commit related to the Hub and Spoke feature will
  change the response to grant the peer a slot when there are peer slots
  available.

* HTTP responses to outgoing Peer connect requests parse redirect IP:ports:
  When the [overlay] configuration section (which is experimental) has
  http_handshake = 1, HTTP redirect responses will have the JSON content-body
  parsed to obtain the redirect IP:port addresses.

* Use a single io_service for HTTP::Server and Overlay:
  This is necessary to allow HTTP::Server to pass sockets to and from Overlay
  and eventually Websockets. Unfortunately Websockets is not so easily changed
  to use an externally provided io_service. This will be addressed in a future
  commit, and is one step necessary ease the restriction on ports configured
  to offer Websocket protocols in the .cfg file.
2014-11-06 16:10:00 -08:00
Vinnie Falco
e37d4043f6 Add missing includes to make headers compile separately 2014-11-03 16:40:57 -08:00
Vinnie Falco
d073425b44 Improved beast::http::message:
* Add headers::erase
* Set http::message version with std::pair
* Use std::pair for headers::value_type
2014-11-03 16:40:57 -08:00
Nicholas Dudfield
825b18cf71 Add bin/stop-test.js shutdown testing script:
This script launches rippled repeatedly and then issues a stop command
after a variable amount of time. This is to test the shutdown of the
application and catch errors.
2014-11-03 16:31:21 -08:00
Vinnie Falco
549ad3204f Fix race conditions closing HTTP I/O objects:
This fixes a case where stop can sometimes skip calling close on some
I/O objects or crash in a rare circumstance where a connection is in the
process of being torn down at the exact time the server is stopped. When
the acceptor receives errors, it logs the error and continues listening
instead of stopping.
2014-11-03 14:11:06 -08:00
Vinnie Falco
35f9499b67 Fix Overlay stop on exit:
The stop sequence for Overlay had a race condition where autoconnect could
be called after close_all, resulting in a hang on exit. This resolves the
problem by putting the close and timer operations on a strand:
* Rename some Overlay members
* Put close on strand and tidy up members
* Use completion handler instead of coroutine for timer
* Use App io_service in PeerFinder
2014-11-03 14:11:05 -08:00
Vinnie Falco
db82c35c17 Remove spurious assert in ResolverAsioImpl 2014-11-03 14:11:05 -08:00
Vinnie Falco
73c74f753c Change to the Application io_service:
* Simplified the implementation and removed class IoServicePool
* The io_service outlives the components of the Application
2014-11-03 14:11:05 -08:00
JoelKatz
a38fb2a5dc Clear the acquiring ledger when shutting down NetworkOPs:
This solves a circular destruction problem on exit.
2014-11-03 14:11:04 -08:00
Donovan Hide
38e99e01f9 Improve nodestore benchmarking:
* Use more succinct while loops on NodeFactory.
* Better formatting of multiple test results.
* Updated benchmarks.
* Use simpler and faster RNG to generate test data.
2014-11-02 07:16:08 -08:00
Donovan Hide
a1f46e84b8 Add new RocksDBQuickFactory for benchmarking:
This new factory is intended for benchmarking against the existing RocksDBFactory and has the following differences.
* Does not use BatchWriter
* Disables WAL for writes to memtable
* Uses a hash index in blocks
* Uses RocksDB OptimizeFor… functions
See Benchmarks.md for further discussion of some of the issues raised by investigation of RocksDB performance.
2014-11-01 07:12:09 -07:00
Donovan Hide
6540804571 Add repeatable NodeStore timing benchmark:
The timing test is changed to overcome possible file buffer cache effects by creating different read access patterns. The unittest-arg command line arguments allow running the benchmarks against any of the available backends and altering the parameters passed in the same format as rippled.cfg. The num_objects parameter permits variation of the number of key/values inserted. The data is random but matches reasonably well the values that rippled might generate.
2014-11-01 07:12:08 -07:00
Howard Hinnant
ffe6707595 Refactor Stoppable:
The Stoppable interface aids in the enforcement of invariants needed to
successful start and stop a multi-threaded application composed of classes
that depend on each other in complex ways.
* Test written to confirm the current behavior.
* Comments updated to reflect the current behavior.
* Public API reduced to what is currently in use.
* Protected data members made private.
* volatile bool members changed to std::atomic<bool>.
* std::atomic<int> members changed to std::atomic<bool>.
* Name storage uses std::string
2014-10-31 21:29:16 -07:00
Tom Ritchford
9b21740c9f Delete temporary directories at the end of tests (RIPD-460). 2014-10-31 21:21:54 -07:00
Tom Ritchford
bd12e2ab95 New class TempDirectory in UnitTestUtilities. 2014-10-31 21:21:54 -07:00
Donovan Hide
bffb5ef8b4 Avoid zero initialization of Blob:
This seemed to improve the performance of the copy, although there did seem to be some byte by byte copying still present. Further investigation recommended.
2014-10-31 20:12:39 -07:00
Donovan Hide
e4c9822d78 Enable processor-specific optimizations when available:
The SConstruct is modified to enable processor specific optimizations on clang and gcc toolchains. This improves the performance of RocksDB's CRC function. It might also enable other used libraries that are in the codebase now or in the future to apply cpu-specific optimisations. The mtune option ensures that a binary compiled on one machine will function on another,
2014-10-31 20:12:39 -07:00
Vinnie Falco
73187d8832 Remove obsolete multitls and proxy websocket features 2014-10-31 15:15:40 -07:00
Vinnie Falco
8101154d5e Remove obsolete websocket PROXY port 2014-10-31 15:15:40 -07:00
Vinnie Falco
c02937fd6f Remove obsolete sections from rippled-example.cfg:
* peer_port_proxy is obsolete since the MultiSocket was removed.
* peer_ssl_cipher_list has no effect, SSL ciphers are hard coded for security.
2014-10-31 15:15:40 -07:00
Vinnie Falco
3430be4075 Add PeerFinder onRedirects function 2014-10-31 13:27:55 -07:00
Vinnie Falco
3f2b6f771f Add streambuf to_string function 2014-10-31 13:27:38 -07:00
Vinnie Falco
6e39b49cc2 Add Json::stream to write Value to a Streambuf 2014-10-31 13:27:33 -07:00
Vinnie Falco
71c34ed4e0 Remove unused ErrorReply function 2014-10-31 13:25:54 -07:00
Vinnie Falco
477178675c Fix parseIniFile for duplicate sections 2014-10-31 13:25:30 -07:00
Vinnie Falco
dbdf68b248 Refactor HTTP::Server to support Universal Port:
These changes are necessary to support the Universal port feature. Synopsis:

* Persist HTTP peer io_service::work lifetime:
This simplification eliminates any potential for bugs caused by incorrect
lifetime management of the io_service::work object.

* Restructure Door to prevent data races, and handle clean exit:
The Server, Door, Door::detector, and Peer objects work together to
correctly implement graceful stop and destructors that block until
all child objects have been destroyed.

Cleanups:
* De-pimpl HTTP::Server
* Rename ServerImpl data members
* Tidy up HTTP::Port interface
2014-10-30 16:02:19 -07:00
Vinnie Falco
2fd139b307 Refactor Overlay and add [overlay] config section (experimental):
These changes prepare Overlay for the Universal Port and Hub and Spoke
features.

* Add [overlay configuration section:
The [overlay] section uses the new BasicConfig interface that
supports key-value pairs in the section. Some exposition is added to the
example cfg file. The new settings for overlay are related to the Hub and
Spoke feature which is currently in development. Production servers should
not set these configuration options, they are clearly marked experimental
in the example cfg file.

Other changes:
* Use _MSC_VER to detect Visual Studio
* Use ssl_bundle in Overlay::Peer
* Use shared_ptr to SSL context in Overlay:
* Removed undocumented PEER_SSL_CIPHER_LIST configuration setting
* Add Section::name: The Section object now stores its name for better diagnostic messages.
2014-10-30 13:55:01 -07:00
Vinnie Falco
a6c2657062 Add shared_ptr<boost::asio::ssl::context> to ssl_bundle:
This gives the ssl_bundle shared ownership of the underlying ssl context
so that ownership of the bundle may be transferred to other classes without
introduce lifetime issues.
2014-10-30 13:55:00 -07:00
Vinnie Falco
78a0bc0e2c Make streambuf buffers_type iterators default constructible 2014-10-30 13:55:00 -07:00
Edward Hennis
d7116d6867 Enable std::array overloads for boost::asio on clang:
* Remove Boost config option from beast config.
* Define from compiler, or let Boost figure out itself.
2014-10-30 13:55:00 -07:00
Josh Juran
edc15b9fa2 Use a self-signed certificate for peers (RIPD-108):
Generate a new RSA key pair and a self-signed X.509v3 certificate to use
with SSL connections to rippled peers.  New credentials are created each
startup.
2014-10-30 13:54:49 -07:00
Josh Juran
93d4b73b2f RippleSSLContext: Add openssl wrappers 2014-10-30 10:52:37 -07:00
Vinnie Falco
8e3849e591 Create Ripple SSL contexts using std::make_shared. 2014-10-30 10:52:36 -07:00
Vinnie Falco
acaa1098f7 Separate beast::http::body from beast::http::message (RIPD-660):
This changes the http::message object to no longer contain a body. It modifies
the parser to store the body in a separate object, or to pass the body data
to a functor. This allows the body to be stored in more flexible ways. For
example, in HTTP responses the body can be generated procedurally instead
of being required to exist entirely in memory at once.
2014-10-29 19:23:53 -07:00
Vinnie Falco
c1a5e88752 Use beast::asio::streambuf in Overlay 2014-10-29 19:23:53 -07:00
Vinnie Falco
74b99014d2 Add beast::asio::basic_streambuf (RIPD-661):
This is class whose interface is identical to the boost::asio::basic_streambuf,
and uses an implementation that stores the data in multiple discontiguous
linear buffers, expanding and shrinking as needed.
2014-10-29 19:23:53 -07:00
Tom Ritchford
9cba944d21 Add Json::to_string:
This allows the declaration for FastWriter to be hidden and makes
conversion of Json::Value objects to strings a little less clunky.
2014-10-29 19:23:52 -07:00
Tom Ritchford
8c1c2f5d05 Eliminate a copy of the string returned by FastWriter 2014-10-29 19:22:44 -07:00
Tom Ritchford
bf0fa8c562 Add 'sample' npm test:
test/sample-test.js is the smallest possible npm test.
2014-10-28 10:59:59 -07:00
Donovan Hide
3e1fc9ba6c Update unit testing command line parser parameters:
A string passed by the '--unittest-arg' command line parameter is passed to
suites when unit tests run and can be used to customize test behavior.
* Add '--unittest-arg' command line argument
* Remove obsolete '--unittest-format' command line argument
2014-10-28 10:55:44 -07:00
Vinnie Falco
4ceba603e4 Improvements to beast::unit_test framework:
* Some runner member functions are now thread-safe.
* De-inline and tidy up declarations and definitions.
* arg() interface allows command lines to be passed to suites.
2014-10-28 10:41:10 -07:00
2731 changed files with 259696 additions and 143409 deletions

6
.gitignore vendored
View File

@@ -31,6 +31,7 @@ Release/*.*
tmp
# Ignore database directory.
db/
db/*.db
db/*.db-*
@@ -75,4 +76,7 @@ My Amplifier XE Results - RippleD
/out.txt
# Build Log
rippled-build.log
rippled-build.log
# Profiling data
gmon.out

View File

@@ -2,24 +2,21 @@ language: cpp
compiler:
- clang
- gcc
env:
- TARGET=debug
- TARGET=debug.nounity
# We can specify any combination of builds here, for example, to
# include release builds, too, uncomment the following lines.
#- TARGET=release
#- TARGET=release.nounity
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq python-software-properties
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo add-apt-repository -y ppa:afrank/boost
- sudo apt-get update -qq
- sudo apt-get install -qq g++-4.8
- sudo apt-get install -qq libboost1.55-all-dev
# We want debug symbols for boost as we install gdb later
- sudo apt-get install -qq libboost1.55-dbg
- | # Setup the BOOST_ROOT
export BOOST_ROOT=$HOME/boost_root
mkdir -p $BOOST_ROOT/stage
ln -s /usr/lib/x86_64-linux-gnu $BOOST_ROOT/stage/lib
ln -s /usr/include/boost $BOOST_ROOT/boost
- | # Try to patch boost
sudo patch /usr/include/boost/bimap/detail/debug/static_error.hpp Builds/travis/static_error.boost.patch
sudo patch /usr/include/boost/config/compiler/clang.hpp Builds/travis/clang.boost.patch
- sudo apt-get install -qq libboost1.57-all-dev
- sudo apt-get install -qq mlocate
- sudo updatedb
- sudo locate libboost | grep /lib | grep -e ".a$"
@@ -44,11 +41,14 @@ before_install:
script:
# Set so any failing command will abort the build
- set -e
# Make sure vcxproj is up to date
- scons vcxproj
- git diff --exit-code
# $CC will be either `clang` or `gcc` (If only we could do -j12 ;)
- scons $CC.debug
# We can be sure we're using the build/$CC.debug variant (-f so never err)
- scons $CC.$TARGET
# We can be sure we're using the build/$CC.$TARGET variant (-f so never err)
- rm -f build/rippled
- export RIPPLED_PATH="$PWD/build/$CC.debug/rippled"
- export RIPPLED_PATH="$PWD/build/$CC.$TARGET/rippled"
# See what we've actually built
- ldd $RIPPLED_PATH
# Run unittests (under gdb)
@@ -59,7 +59,7 @@ script:
# gdb --help
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args $RIPPLED_PATH --unittest
- npm install
# Use build/(gcc|clang).debug/rippled
# Use build/(gcc|clang).$TARGET/rippled
- |
echo "exports.default_server_config = {\"rippled_path\" : \"$RIPPLED_PATH\"};" > test/config.js

View File

@@ -1,4 +1,4 @@
# Maintainer: Roberto Catini <roberto.catini@gmail.com>
# Maintainer: Roberto Catini <roberto.catini@gmail.com>
pkgname=rippled
pkgrel=1
@@ -21,7 +21,7 @@ pkgver() {
build() {
cd "$srcdir/$pkgname"
scons build/rippled
scons
}
check() {

View File

@@ -0,0 +1,23 @@
FROM ubuntu
MAINTAINER Torrie Fischer <torrie@ripple.com>
RUN apt-get update -qq &&\
apt-get install -qq software-properties-common &&\
apt-add-repository -y ppa:ubuntu-toolchain-r/test &&\
apt-add-repository -y ppa:afrank/boost &&\
apt-get update -qq
RUN apt-get purge -qq libboost1.48-dev &&\
apt-get install -qq libprotobuf8 libboost1.57-all-dev
RUN mkdir -p /srv/rippled/data
VOLUME /srv/rippled/data/
ENTRYPOINT ["/srv/rippled/bin/rippled"]
CMD ["--conf", "/srv/rippled/data/rippled.cfg"]
EXPOSE 51235/udp
EXPOSE 5005/tcp
ADD ./rippled.cfg /srv/rippled/data/rippled.cfg
ADD ./rippled /srv/rippled/bin/

13
Builds/Docker/build-ci.sh Executable file
View File

@@ -0,0 +1,13 @@
set -e
mkdir -p build/docker/
cp doc/rippled-example.cfg build/clang.debug/rippled build/docker/
cp Builds/Docker/Dockerfile-testnet build/docker/Dockerfile
mv build/docker/rippled-example.cfg build/docker/rippled.cfg
strip build/docker/rippled
docker build -t ripple/rippled:$CIRCLE_SHA1 build/docker/
docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:latest
if [ -z "$CIRCLE_PR_NUMBER" ]; then
docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:$CIRCLE_BRANCH
fi

16
Builds/Docker/push-to-hub.sh Executable file
View File

@@ -0,0 +1,16 @@
set -e
if [ -z "$DOCKER_EMAIL" -o -z "$DOCKER_USERNAME" -o -z "$DOCKER_PASSWORD" ];then
echo "Docker credentials are not set. Can't login to docker, no containers will be pushed."
exit 0
fi
if [ -n "$CIRCLE_PR_NUMBER" ]; then
echo "Not pushing results of a pull request build."
exit 0
fi
docker login -e $DOCKER_EMAIL -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
docker push ripple/rippled:$CIRCLE_SHA1
docker push ripple/rippled:$CIRCLE_BRANCH
docker push ripple/rippled:latest

31
Builds/Eclipse/README.md Normal file
View File

@@ -0,0 +1,31 @@
**Requirements**
1. Java Runtime Environment (JRE)
2. Eclipse with CDT (tested on Luna):
http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/lunasr2
3. Eclipse SCons plugin: http://sconsolidator.com/
**WARNING**: by default the SCons plugin uses 16 threads. Go to
*Window->Preferences->SCons->Build Settings* in Eclipse and make it
use only 4-8 jobs(threads) or whatever you feel confortable with. It will
positively freeze your system if you run with 16 threads/jobs.
![scons](scons.png)
**Getting Started**
After setting up Eclipse just do a File->New->Other...
Select: C/C++ / New SCons project from existing source
Point the importer to the folder where the SConstruct resides (the root
folder of your git workspace normally)
**Build**
Just hit Project->Build All in Eclipse to get started. And remember to not
let it run 16 threads!
**Debug**
Start a new Eclipse debug configuration and set binary to run to build/rippled
(assuming you have built it).
![debug](debug.png)

BIN
Builds/Eclipse/debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
Builds/Eclipse/scons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

180
Builds/Test.py Executable file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python
# This file is part of rippled: https://github.com/ripple/rippled
# Copyright (c) 2012 - 2015 Ripple Labs Inc.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
Invocation:
./Builds/Test.py - builds and tests all configurations
#
# The build must succeed without shell aliases for this to work.
#
# Common problems:
# 1) Boost not found. Solution: export BOOST_ROOT=[path to boost folder]
# 2) OpenSSL not found. Solution: export OPENSSL_ROOT=[path to OpenSSL folder]
# 3) scons is an alias. Solution: Create a script named "scons" somewhere in
# your $PATH (eg. ~/bin/scons will often work).
# #!/bin/sh
# python /C/Python27/Scripts/scons.py "${@}"
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import argparse
import itertools
import os
import platform
import re
import subprocess
import sys
IS_WINDOWS = platform.system().lower() == 'windows'
if IS_WINDOWS:
BINARY_RE = re.compile(r'build\\([^\\]+)\\rippled.exe')
else:
BINARY_RE = re.compile(r'build/([^/]+)/rippled')
ALL_TARGETS = ['debug', 'release']
parser = argparse.ArgumentParser(
description='Test.py - run ripple tests'
)
parser.add_argument(
'--all', '-a',
action='store_true',
help='Build all configurations.',
)
parser.add_argument(
'--keep_going', '-k',
action='store_true',
help='Keep going after one configuration has failed.',
)
parser.add_argument(
'--silent', '-s',
action='store_true',
help='Silence all messages except errors',
)
parser.add_argument(
'--verbose', '-v',
action='store_true',
help=('Report more information about which commands are executed and the '
'results.'),
)
parser.add_argument(
'--test', '-t',
default='',
help='Add a prefix for unit tests',
)
parser.add_argument(
'scons_args',
default=(),
nargs='*'
)
ARGS = parser.parse_args()
def shell(*cmd, **kwds):
"Execute a shell command and return the output."
silent = kwds.pop('silent', ARGS.silent)
verbose = not silent and kwds.pop('verbose', ARGS.verbose)
if verbose:
print('$', ' '.join(cmd))
kwds['shell'] = IS_WINDOWS
process = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
**kwds)
lines = []
count = 0
for line in process.stdout:
lines.append(line)
if verbose:
print(line, end='')
elif not silent:
count += 1
if count >= 80:
print()
count = 0
else:
print('.', end='')
if not verbose and count:
print()
process.wait()
return process.returncode, lines
if __name__ == '__main__':
args = list(ARGS.scons_args)
if ARGS.all:
for a in ALL_TARGETS:
if a not in args:
args.append(a)
print('Building:', *(args or ['(default)']))
# Build everything.
resultcode, lines = shell('scons', *args)
if resultcode:
print('Build FAILED:')
if not ARGS.verbose:
print(*lines, sep='')
exit(1)
# Now extract the executable names and corresponding targets.
failed = []
_, lines = shell('scons', '-n', '--tree=derived', *args, silent=True)
for line in lines:
match = BINARY_RE.search(line)
if match:
executable, target = match.group(0, 1)
print('Unit tests for', target)
testflag = '--unittest'
if ARGS.test:
testflag += ('=' + ARGS.test)
resultcode, lines = shell(executable, testflag)
if resultcode:
print('ERROR:', *lines, sep='')
failed.append([target, 'unittest'])
if not ARGS.keep_going:
break
ARGS.verbose and print(*lines, sep='')
print('npm tests for', target)
resultcode, lines = shell('npm', 'test', '--rippled=' + executable)
if resultcode:
print('ERROR:\n', *lines, sep='')
failed.append([target, 'npm'])
if not ARGS.keep_going:
break
else:
ARGS.verbose and print(*lines, sep='')
if failed:
print('FAILED:', *(':'.join(f) for f in failed))
exit(1)
else:
print('Success')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.30110.0
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
Project("{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
debug.classic|x64 = debug.classic|x64
debug|x64 = debug|x64
release.classic|x64 = release.classic|x64
release|x64 = release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|Win32.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|Win32.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.Build.0 = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.ActiveCfg = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.Build.0 = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.ActiveCfg = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.Build.0 = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.Build.0 = release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,5 +1,5 @@
Name: rippled
Version: 0.26.4-sp1
Version: 0.29.0-hf1
Release: 1%{?dist}
Summary: Ripple peer-to-peer network daemon
@@ -50,4 +50,3 @@ rm -rf %{buildroot}
/usr/bin/rippled
/usr/share/rippled/LICENSE
/etc/rippled/rippled-example.cfg

View File

@@ -1,3 +1,77 @@
![Ripple](/images/ripple.png)
#The Worlds Fastest and Most Secure Payment System
**What is Ripple?**
Ripple is the open-source, distributed payment protocol that enables instant
payments with low fees, no chargebacks, and currency flexibility (for example
dollars, yen, euros, bitcoins, or even loyalty points). Businesses of any size
can easily build payment solutions such as banking or remittance apps, and
accelerate the movement of money. Ripple enables the world to move value the
way it moves information on the Internet.
![Ripple Network](images/network.png)
**What is a Gateway?**
Ripple works with gateways: independent businesses which hold customer
deposits in various currencies such as U.S. dollars (USD) or Euros (EUR),
in exchange for providing cryptographically-signed issuances that users can
send and trade with one another in seconds on the Ripple network. Within the
protocol, exchanges between multiple currencies can occur atomically without
any central authority to monitor them. Later, customers can withdraw their
Ripple balances from the gateways that created those issuances.
**How do Ripple payments work?**
A sender specifies the amount and currency the recipient should receive and
Ripple automatically converts the senders available currencies using the
distributed order books integrated into the Ripple protocol. Independent third
parties acting as market makers provide liquidity in these order books.
Ripple uses a pathfinding algorithm that considers currency pairs when
converting from the source to the destination currency. This algorithm searches
for a series of currency swaps that gives the user the lowest cost. Since
anyone can participate as a market maker, market forces drive fees to the
lowest practical level.
**What can you do with Ripple?**
The protocol is entirely open-source and the networks shared ledger is public
information, so no central authority prevents anyone from participating. Anyone
can become a market maker, create a wallet or a gateway, or monitor network
behavior. Competition drives down spreads and fees, making the network useful
to everyone.
###Key Protocol Features
1. XRP is Ripples native [cryptocurrency]
(http://en.wikipedia.org/wiki/Cryptocurrency) with a fixed supply that
decreases slowly over time, with no mining. XRP acts as a bridge currency, and
pays for transaction fees that protect the network against spam.
![XRP as a bridge currency](/images/vehicle_currency.png)
2. Pathfinding discovers cheap and efficient payment paths through multiple
[order books](https://www.ripplecharts.com) allowing anyone to [trade](https://www.rippletrade.com) anything. When two accounts arent linked by relationships of trust, the Ripple pathfinding engine considers intermediate links and order books to produce a set of possible paths the transaction can take. When the payment is processed, the liquidity along these paths is iteratively consumed in best-first order.
![Pathfinding from Dollars to Euro](/images/pathfinding.png)
3. [Consensus](https://www.youtube.com/watch?v=pj1QVb1vlC0) confirms
transactions in an atomic fashion, without mining, ensuring efficient use of
resources.
[transact]: https://ripple.com/files/ripple-FIs.pdf
[build]: https://ripple.com/build/
[transact.png]: /images/transact.png
[build.png]: /images/build.png
[contribute.png]: /images/contribute.png
###Join The Ripple Community
|![Transact][transact.png]|![Build][build.png]|![Contribute][contribute.png]|
|:-----------------------:|:-----------------:|:---------------------------:|
|[Transact on the fastest payment infrastructure][transact]|[Build Imaginative Apps][build]|Contribute to the Ripple Protocol Implementation|
#rippled - Ripple P2P server
##[![Build Status](https://travis-ci.org/ripple/rippled.png?branch=develop)](https://travis-ci.org/ripple/rippled)
@@ -10,6 +84,9 @@ This is the repository for Ripple's `rippled`, reference P2P server.
###Setup instructions:
* https://ripple.com/wiki/Rippled_setup_instructions
###Issues
* https://ripplelabs.atlassian.net/browse/RIPD
### Repository Contents
#### ./bin
@@ -37,5 +114,16 @@ Ripple is open source and permissively licensed under the ISC license. See the
LICENSE file for more details.
###For more information:
* https://ripple.com
* https://ripple.com/wiki
* Ripple Wiki - https://ripple.com/wiki/
* Ripple Primer - https://ripple.com/ripple_primer.pdf
* Ripple Primer (Market Making) - https://ripple.com/ripple-mm.pdf
* Ripple Gateway Primer - https://ripple.com/ripple-gateways.pdf
* Consensus - https://wiki.ripple.com/Consensus
- - -
Copyright © 2015, Ripple Labs. All rights reserved.
Portions of this document, including but not limited to the Ripple logo, images
and image templates are the property of Ripple Labs and cannot be copied or
used without permission.

View File

@@ -11,14 +11,17 @@
all All available variants
debug All available debug variants
release All available release variants
profile All available profile variants
clang All clang variants
clang.debug clang debug variant
clang.release clang release variant
clang.profile clang profile variant
gcc All gcc variants
gcc.debug gcc debug variant
gcc.release gcc release variant
gcc.profile gcc profile variant
msvc All msvc variants
msvc.debug MSVC debug variant
@@ -26,10 +29,42 @@
vcxproj Generate Visual Studio 2013 project file
count Show line count metrics
Any individual target can also have ".nounity" appended for a classic,
non unity build. Example:
scons gcc.debug.nounity
If the clang toolchain is detected, then the default target will use it, else
the gcc toolchain will be used. On Windows environments, the MSVC toolchain is
also detected.
The following environment variables modify the build environment:
CLANG_CC
CLANG_CXX
CLANG_LINK
If set, a clang toolchain will be used. These must all be set together.
GNU_CC
GNU_CXX
GNU_LINK
If set, a gcc toolchain will be used (unless a clang toolchain is
detected first). These must all be set together.
CXX
If set, used to detect a toolchain.
BOOST_ROOT
Path to the boost directory.
OPENSSL_ROOT
Path to the openssl directory.
The following extra options may be used:
--ninja Generate a `build.ninja` build file for the specified target
(see: https://martine.github.io/ninja/). Only gcc and clang targets
are supported.
'''
#
'''
@@ -53,11 +88,16 @@ import time
import SCons.Action
sys.path.append(os.path.join('src', 'beast', 'site_scons'))
sys.path.append(os.path.join('src', 'ripple', 'site_scons'))
import Beast
import scons_to_ninja
#------------------------------------------------------------------------------
AddOption('--ninja', dest='ninja', action='store_true',
help='generate ninja build file build.ninja')
def parse_time(t):
return time.strptime(t, '%a %b %d %H:%M:%S %Z %Y')
@@ -83,6 +123,29 @@ def check_openssl():
(CHECK_LINE, CHECK_COMMAND))
def set_implicit_cache():
'''Use implicit_cache on some targets to improve build times.
By default, scons scans each file for include dependecies. The implicit
cache flag lets you cache these dependencies for later builds, and will
only rescan files that change.
Failure cases are:
1) If the include search paths are changed (i.e. CPPPATH), then a file
may not be rebuilt.
2) If a same-named file has been added to a directory that is earlier in
the search path than the directory in which the file was found.
Turn on if this build is for a specific debug target (i.e. clang.debug)
If one of the failure cases applies, you can force a rescan of dependencies
using the command line option `--implicit-deps-changed`
'''
if len(COMMAND_LINE_TARGETS) == 1:
s = COMMAND_LINE_TARGETS[0].split('.')
if len(s) > 1 and 'debug' in s:
SetOption('implicit_cache', 1)
def import_environ(env):
'''Imports environment settings into the construction environment'''
def set(keys):
@@ -199,7 +262,11 @@ def config_base(env):
)
check_openssl()
env.Append(CPPDEFINES=['OPENSSL_NO_SSL2'])
env.Append(CPPDEFINES=[
'OPENSSL_NO_SSL2'
,'DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER'
,{'HAVE_USLEEP' : '1'}
])
try:
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
@@ -245,7 +312,7 @@ def config_env(toolchain, variant, env):
if variant == 'debug':
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
elif variant == 'release':
elif variant == 'release' or variant == 'profile':
env.Append(CPPDEFINES=['NDEBUG'])
if toolchain in Split('clang gcc'):
@@ -263,14 +330,32 @@ def config_env(toolchain, variant, env):
'-g' # generate debug symbols
])
env.Append(LINKFLAGS=[
'-rdynamic',
'-g',
])
if variant == 'profile':
env.Append(CCFLAGS=[
'-p',
'-pg',
])
env.Append(LINKFLAGS=[
'-p',
'-pg',
])
if toolchain == 'clang':
env.Append(CCFLAGS=['-Wno-redeclared-class-member'])
env.Append(CPPDEFINES=['BOOST_ASIO_HAS_STD_ARRAY'])
env.Append(CXXFLAGS=[
'-frtti',
'-std=c++11',
'-Wno-invalid-offsetof'])
env.Append(CPPDEFINES=['_FILE_OFFSET_BITS=64'])
if Beast.system.osx:
env.Append(CPPDEFINES={
'BEAST_COMPILE_OBJECTIVE_CPP': 1,
@@ -298,11 +383,10 @@ def config_env(toolchain, variant, env):
'boost_program_options',
'boost_regex',
'boost_system',
'boost_thread'
]
# We prefer static libraries for boost
if env.get('BOOST_ROOT'):
# Need to add boost_thread. Not needed when dynamic linking is used.
boost_libs += ['boost_thread']
static_libs = ['%s/stage/lib/lib%s.a' % (env['BOOST_ROOT'], l) for
l in boost_libs]
if all(os.path.exists(f) for f in static_libs):
@@ -324,22 +408,12 @@ def config_env(toolchain, variant, env):
else:
env.Append(LIBS=['rt'])
env.Append(LINKFLAGS=[
'-rdynamic'
])
if variant == 'release':
env.Append(CCFLAGS=[
'-O3',
'-fno-strict-aliasing'
])
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
env.Append(CPPDEFINES={'GIT_COMMIT_ID' : '\'"%s"\'' % id })
if toolchain == 'clang':
if Beast.system.osx:
env.Replace(CC='clang', CXX='clang++', LINK='clang++')
@@ -466,6 +540,7 @@ def config_env(toolchain, variant, env):
# Configure the base construction environment
root_dir = Dir('#').srcnode().get_abspath() # Path to this SConstruct file
build_dir = os.path.join('build')
base = Environment(
toolpath=[os.path.join ('src', 'beast', 'site_scons', 'site_tools')],
tools=['default', 'Protoc', 'VSProject'],
@@ -477,10 +552,14 @@ base.Append(CPPPATH=[
'src',
os.path.join('src', 'beast'),
os.path.join(build_dir, 'proto'),
os.path.join('src','soci','src'),
])
base.Decider('MD5-timestamp')
set_implicit_cache()
# Configure the toolchains, variants, default toolchain, and default target
variants = ['debug', 'release']
variants = ['debug', 'release', 'profile']
all_toolchains = ['clang', 'gcc', 'msvc']
if Beast.system.osx:
toolchains = ['clang']
@@ -501,6 +580,8 @@ else:
default_toolchain = 'clang'
else:
raise ValueError("Don't understand toolchains in " + str(toolchains))
default_tu_style = 'unity'
default_variant = 'release'
default_target = None
@@ -520,6 +601,7 @@ class ObjectBuilder(object):
self.env = env
self.variant_dirs = variant_dirs
self.objects = []
self.child_envs = []
def add_source_files(self, *filenames, **kwds):
for filename in filenames:
@@ -527,144 +609,318 @@ class ObjectBuilder(object):
if kwds:
env = env.Clone()
env.Prepend(**kwds)
path = UNITY_BUILD_DIRECTORY + filename
o = env.Object(Beast.variantFile(path, self.variant_dirs))
self.child_envs.append(env)
o = env.Object(Beast.variantFile(filename, self.variant_dirs))
self.objects.append(o)
def list_sources(base, suffixes):
def _iter(base):
for parent, dirs, files in os.walk(base):
files = [f for f in files if not f[0] == '.']
dirs[:] = [d for d in dirs if not d[0] == '.']
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] and r[1] in suffixes:
yield os.path.normpath(path)
return list(_iter(base))
def append_sources(result, *filenames, **kwds):
result.append([filenames, kwds])
def get_soci_sources(style):
result = []
cpp_path = [
'src/soci/src/core',
'src/sqlite', ]
append_sources(result,
'src/ripple/unity/soci.cpp',
CPPPATH=cpp_path)
if style == 'unity':
append_sources(result,
'src/ripple/unity/soci_ripple.cpp',
CPPPATH=cpp_path)
return result
def get_common_sources():
result = []
append_sources(
result,
'src/ripple/unity/secp256k1.cpp',
CPPPATH=[
'src/secp256k1',
])
return result
def get_classic_sources():
result = []
append_sources(
result,
*list_sources('src/ripple/core', '.cpp'),
CPPPATH=[
'src/soci/src/core',
'src/sqlite']
)
append_sources(result, *list_sources('src/ripple/app', '.cpp'))
append_sources(result, *list_sources('src/ripple/basics', '.cpp'))
append_sources(result, *list_sources('src/ripple/crypto', '.cpp'))
append_sources(result, *list_sources('src/ripple/json', '.cpp'))
append_sources(result, *list_sources('src/ripple/ledger', '.cpp'))
append_sources(result, *list_sources('src/ripple/legacy', '.cpp'))
append_sources(result, *list_sources('src/ripple/net', '.cpp'))
append_sources(result, *list_sources('src/ripple/overlay', '.cpp'))
append_sources(result, *list_sources('src/ripple/peerfinder', '.cpp'))
append_sources(result, *list_sources('src/ripple/protocol', '.cpp'))
append_sources(result, *list_sources('src/ripple/rpc', '.cpp'))
append_sources(result, *list_sources('src/ripple/shamap', '.cpp'))
append_sources(result, *list_sources('src/ripple/test', '.cpp'))
append_sources(
result,
*list_sources('src/ripple/nodestore', '.cpp'),
CPPPATH=[
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
result += get_soci_sources('classic')
result += get_common_sources()
return result
def get_unity_sources():
result = []
append_sources(
result,
'src/ripple/unity/app_ledger.cpp',
'src/ripple/unity/app_main.cpp',
'src/ripple/unity/app_misc.cpp',
'src/ripple/unity/app_paths.cpp',
'src/ripple/unity/app_tests.cpp',
'src/ripple/unity/app_tx.cpp',
'src/ripple/unity/core.cpp',
'src/ripple/unity/basics.cpp',
'src/ripple/unity/crypto.cpp',
'src/ripple/unity/ledger.cpp',
'src/ripple/unity/net.cpp',
'src/ripple/unity/overlay.cpp',
'src/ripple/unity/peerfinder.cpp',
'src/ripple/unity/json.cpp',
'src/ripple/unity/protocol.cpp',
'src/ripple/unity/rpcx.cpp',
'src/ripple/unity/shamap.cpp',
'src/ripple/unity/test.cpp',
)
append_sources(
result,
'src/ripple/unity/nodestore.cpp',
CPPPATH=[
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
result += get_soci_sources('unity')
result += get_common_sources()
return result
# Declare the targets
aliases = collections.defaultdict(list)
msvc_configs = []
for toolchain in all_toolchains:
for variant in variants:
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
object_builder = ObjectBuilder(env, variant_dirs)
object_builder.add_source_files(
'app.cpp',
'app1.cpp',
'app2.cpp',
'app3.cpp',
'app4.cpp',
'app5.cpp',
'app6.cpp',
'app7.cpp',
'app8.cpp',
'app9.cpp',
'basics.cpp',
'beast.cpp',
'common.cpp',
'core.cpp',
'data.cpp',
'http.cpp',
'json.cpp',
'net.cpp',
'overlay.cpp',
'peerfinder.cpp',
'protobuf.cpp',
'ripple.proto.cpp',
'resource.cpp',
'rpcx.cpp',
'sitefiles.cpp',
'sslutil.cpp',
'types.cpp',
'validators.cpp',
'websocket.cpp',
)
object_builder.add_source_files(
'beastc.c',
CCFLAGS=['-Wno-array-bounds'])
def should_prepare_target(cl_target,
style, toolchain, variant):
if not cl_target:
# default target
return (style == default_tu_style and
toolchain == default_toolchain and
variant == default_variant)
if 'vcxproj' in cl_target:
return toolchain == 'msvc'
s = cl_target.split('.')
if style == 'unity' and 'nounity' in s:
return False
if len(s) == 1:
return ('all' in cl_target or
variant in cl_target or
toolchain in cl_target)
if len(s) == 2 or len(s) == 3:
return s[0] == toolchain and s[1] == variant
object_builder.add_source_files(
'nodestore.cpp',
CPPPATH=[
'src/leveldb/include',
#'src/hyperleveldb/include', # hyper
'src/rocksdb2/include',
]
)
return True # A target we don't know about, better prepare to build it
if 'gcc' in toolchain:
no_uninitialized_warning = {'CCFLAGS': ['-Wno-maybe-uninitialized']}
else:
no_uninitialized_warning = {}
object_builder.add_source_files(
'leveldb.cpp',
CPPPATH=[
'src/leveldb/',
'src/leveldb/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
def should_prepare_targets(style, toolchain, variant):
if not COMMAND_LINE_TARGETS:
return should_prepare_target(None, style, toolchain, variant)
for t in COMMAND_LINE_TARGETS:
if should_prepare_target(t, style, toolchain, variant):
return True
object_builder.add_source_files(
'hyperleveldb.cpp',
CPPPATH=[
'src/hyperleveldb',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
def should_build_ninja(style, toolchain, variant):
"""
Return True if a ninja build file should be generated.
object_builder.add_source_files(
'rocksdb.cpp',
CPPPATH=[
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
Typically, scons will be called as follows to generate a ninja build file:
`scons ninja=1 gcc.debug` where `gcc.debug` may be replaced with any of our
non-visual studio targets. Raise an exception if we cannot generate the
requested ninja build file (for example, if multiple targets are requested).
"""
if not GetOption('ninja'):
return False
if len(COMMAND_LINE_TARGETS) != 1:
raise Exception('Can only generate a ninja file for a single target')
cl_target = COMMAND_LINE_TARGETS[0]
if 'vcxproj' in cl_target:
raise Exception('Cannot generate a ninja file for a vcxproj')
s = cl_target.split('.')
if ( style == 'unity' and 'nounity' in s or
style == 'classic' and 'nounity' not in s or
len(s) == 1 ):
return False
if len(s) == 2 or len(s) == 3:
return s[0] == toolchain and s[1] == variant
return False
object_builder.add_source_files(
'snappy.cpp',
CCFLAGS=['-Wno-unused-function'],
CPPPATH=[
'src/snappy/snappy',
'src/snappy/config',
]
)
for tu_style in ['classic', 'unity']:
if tu_style == 'classic':
sources = get_classic_sources()
else:
sources = get_unity_sources()
for toolchain in all_toolchains:
for variant in variants:
if not should_prepare_targets(tu_style, toolchain, variant):
continue
if variant == 'profile' and toolchain == 'msvc':
continue
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
if tu_style == 'classic':
variant_name += '.nounity'
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
if toolchain == "clang" and Beast.system.osx:
object_builder.add_source_files('beastobjc.mm')
object_builder = ObjectBuilder(env, variant_dirs)
target = env.Program(
target=os.path.join(variant_dir, 'rippled'),
source=object_builder.objects
for s, k in sources:
object_builder.add_source_files(*s, **k)
git_commit_tag = {}
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
git_commit_tag = {'CPPDEFINES':
{'GIT_COMMIT_ID' : '\'"%s"\'' % id }}
object_builder.add_source_files(
'src/ripple/unity/git_id.cpp',
**git_commit_tag)
object_builder.add_source_files(
'src/beast/beast/unity/hash_unity.cpp',
'src/ripple/unity/beast.cpp',
'src/ripple/unity/lz4.c',
'src/ripple/unity/protobuf.cpp',
'src/ripple/unity/ripple.proto.cpp',
'src/ripple/unity/resource.cpp',
'src/ripple/unity/server.cpp',
'src/ripple/unity/validators.cpp',
'src/ripple/unity/websocket02.cpp'
)
if toolchain == default_toolchain and variant == default_variant:
default_target = target
install_target = env.Install (build_dir, source=default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[variant].extend(target)
aliases[toolchain].extend(target)
env.Alias(variant_name, target)
object_builder.add_source_files(
'src/ripple/unity/beastc.c',
CCFLAGS = ([] if toolchain == 'msvc' else ['-Wno-array-bounds']))
if 'gcc' in toolchain:
no_uninitialized_warning = {'CCFLAGS': ['-Wno-maybe-uninitialized']}
else:
no_uninitialized_warning = {}
object_builder.add_source_files(
'src/ripple/unity/ed25519.c',
CPPPATH=[
'src/ed25519-donna',
]
)
object_builder.add_source_files(
'src/ripple/unity/rocksdb.cpp',
CPPPATH=[
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder.add_source_files(
'src/ripple/unity/snappy.cpp',
CCFLAGS=([] if toolchain == 'msvc' else ['-Wno-unused-function']),
CPPPATH=[
'src/snappy/snappy',
'src/snappy/config',
]
)
object_builder.add_source_files(
'src/ripple/unity/websocket04.cpp',
CPPPATH='src/websocketpp',
)
if toolchain == "clang" and Beast.system.osx:
object_builder.add_source_files('src/ripple/unity/beastobjc.mm')
target = env.Program(
target=os.path.join(variant_dir, 'rippled'),
source=object_builder.objects
)
if tu_style == default_tu_style:
if toolchain == default_toolchain and (
variant == default_variant):
default_target = target
install_target = env.Install (build_dir, source=default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[toolchain].extend(target)
elif toolchain == 'msvc':
config = env.VSProjectConfig(variant + ".classic", 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases[variant].extend(target)
env.Alias(variant_name, target)
# ninja support
if should_build_ninja(tu_style, toolchain, variant):
print('Generating ninja: {}:{}:{}'.format(tu_style, toolchain, variant))
scons_to_ninja.GenerateNinjaFile(
[object_builder.env] + object_builder.child_envs,
dest_file='build.ninja')
for key, value in aliases.iteritems():
env.Alias(key, value)
@@ -675,3 +931,32 @@ vcxproj = base.VSProject(
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
VSPROJECT_CONFIGS = msvc_configs)
base.Alias('vcxproj', vcxproj)
#-------------------------------------------------------------------------------
# Adds a phony target to the environment that always builds
# See: http://www.scons.org/wiki/PhonyTargets
def PhonyTargets(env = None, **kw):
if not env: env = DefaultEnvironment()
for target, action in kw.items():
env.AlwaysBuild(env.Alias(target, [], action))
# Build the list of rippled source files that hold unit tests
def do_count(target, source, env):
def list_testfiles(base, suffixes):
def _iter(base):
for parent, _, files in os.walk(base):
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] in suffixes:
if r[0].endswith('.test'):
yield os.path.normpath(path)
return list(_iter(base))
testfiles = list_testfiles(os.path.join('src', 'ripple'), env.get('CPPSUFFIXES'))
lines = 0
for f in testfiles:
lines = lines + sum(1 for line in open(f))
print "Total unit test lines: %d" % lines
PhonyTargets(env, count = do_count)

77
appveyor.yml Normal file
View File

@@ -0,0 +1,77 @@
# Set environment variables.
environment:
PYTHON: C:/Python27-x64
# We bundle up protoc.exe and only the parts of boost and openssl we need so
# that it's a small download. We also use appveyor's free cache, avoiding fees
# downloading from S3 each time.
# TODO: script to create this package.
RIPPLED_DEPS_URL: https://s3-ap-northeast-1.amazonaws.com/history-replay/rippled_deps.zip
# Other dependencies we just download each time.
PIP_URL: https://bootstrap.pypa.io/get-pip.py
PYWIN32_URL: https://downloads.sourceforge.net/project/pywin32/pywin32/Build%20219/pywin32-219.win-amd64-py2.7.exe
# Scons honours these environment variables, setting the include/lib paths.
BOOST_ROOT: C:/rippled_deps/boost
OPENSSL_ROOT: C:/rippled_deps/openssl
# At the end of each successful build we cache this directory. It must be less
# than 100MB total compressed.
cache:
- "C:\\rippled_deps"
# This means we'll download a zip of the branch we want, rather than the full
# history.
shallow_clone: true
install:
# We want easy_install, python and protoc.exe on PATH.
- SET PATH=%PYTHON%;%PYTHON%/Scripts;C:/rippled_deps;%PATH%
# `ps` prefix means the command is executed by powershell.
- ps: Start-FileDownload $env:PIP_URL
- ps: Start-FileDownload $env:PYWIN32_URL
# Installing pip will install setuptools/easy_install.
- python get-pip.py
# Pip has some problems installing scons on windows so we use easy install.
- easy_install scons
# Scons has problems with parallel builds on windows without pywin32.
- easy_install pywin32-219.win-amd64-py2.7.exe
# (easy_install can do headless installs of .exe wizards)
# Download dependencies if appveyor didn't restore them from the cache.
# Use 7zip to unzip.
- ps: |
if (-not(Test-Path 'C:/rippled_deps')) {
Start-FileDownload "$env:RIPPLED_DEPS_URL"
7z x rippled_deps.zip -oC:\ -y > $null
}
# TODO: This is giving me grief
# artifacts:
# # Save rippled.exe in the cloud after each build.
# - path: "build\\rippled.exe"
build_script:
# We set the environment variables needed to put compilers on the PATH.
- '"%VS120COMNTOOLS%../../VC/vcvarsall.bat" x86_amd64'
# Show which version of the compiler we are using.
- cl
- scons msvc.debug -j%NUMBER_OF_PROCESSORS%
after_build:
# Put our executable in a place where npm test can find it.
- ps: cp build/msvc.debug/rippled.exe build
- ps: ls build
test_script:
# Run the unit tests
- build\\rippled --unittest
# Run the integration tests
- npm install
- npm test

2
bin/LT
View File

@@ -1 +1 @@
LedgerTool.py
python/LedgerTool.py

1
bin/manifest Symbolic link
View File

@@ -0,0 +1 @@
python/Manifest.py

7
bin/python/Manifest.py Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env python
import sys
from ripple.util import Sign
result = Sign.run_command(sys.argv[1:])
exit(0 if result else -1)

View File

@@ -0,0 +1,14 @@
__all__ = ["curves", "der", "ecdsa", "ellipticcurve", "keys", "numbertheory",
"test_pyecdsa", "util", "six"]
from .keys import SigningKey, VerifyingKey, BadSignatureError, BadDigestError
from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1
_hush_pyflakes = [SigningKey, VerifyingKey, BadSignatureError, BadDigestError,
NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1]
del _hush_pyflakes
# This code comes from http://github.com/warner/python-ecdsa
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions

View File

@@ -0,0 +1,183 @@
# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
# directories (produced by setup.py build) will contain a much shorter file
# that just contains the computed version number.
# This file is released into the public domain. Generated by
# versioneer-0.12 (https://github.com/warner/python-versioneer)
# these strings will be replaced by git during git-archive
git_refnames = " (HEAD, master)"
git_full = "e7a6daff51221b8edd888cff404596ef90432869"
# these strings are filled in when 'setup.py versioneer' creates _version.py
tag_prefix = "python-ecdsa-"
parentdir_prefix = "ecdsa-"
versionfile_source = "ecdsa/_version.py"
import os, sys, re, subprocess, errno
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False):
assert isinstance(commands, list)
p = None
for c in commands:
try:
# remember shell=False, so use git.cmd on windows, not just git
p = subprocess.Popen([c] + args, cwd=cwd, stdout=subprocess.PIPE,
stderr=(subprocess.PIPE if hide_stderr
else None))
break
except EnvironmentError:
e = sys.exc_info()[1]
if e.errno == errno.ENOENT:
continue
if verbose:
print("unable to run %s" % args[0])
print(e)
return None
else:
if verbose:
print("unable to find command, tried %s" % (commands,))
return None
stdout = p.communicate()[0].strip()
if sys.version >= '3':
stdout = stdout.decode()
if p.returncode != 0:
if verbose:
print("unable to run %s (error)" % args[0])
return None
return stdout
def versions_from_parentdir(parentdir_prefix, root, verbose=False):
# Source tarballs conventionally unpack into a directory that includes
# both the project name and a version string.
dirname = os.path.basename(root)
if not dirname.startswith(parentdir_prefix):
if verbose:
print("guessing rootdir is '%s', but '%s' doesn't start with prefix '%s'" %
(root, dirname, parentdir_prefix))
return None
return {"version": dirname[len(parentdir_prefix):], "full": ""}
def git_get_keywords(versionfile_abs):
# the code embedded in _version.py can just fetch the value of these
# keywords. When used from setup.py, we don't want to import _version.py,
# so we do it with a regexp instead. This function is not used from
# _version.py.
keywords = {}
try:
f = open(versionfile_abs,"r")
for line in f.readlines():
if line.strip().startswith("git_refnames ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["refnames"] = mo.group(1)
if line.strip().startswith("git_full ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["full"] = mo.group(1)
f.close()
except EnvironmentError:
pass
return keywords
def git_versions_from_keywords(keywords, tag_prefix, verbose=False):
if not keywords:
return {} # keyword-finding function failed to find keywords
refnames = keywords["refnames"].strip()
if refnames.startswith("$Format"):
if verbose:
print("keywords are unexpanded, not using")
return {} # unexpanded, so not in an unpacked git-archive tarball
refs = set([r.strip() for r in refnames.strip("()").split(",")])
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
TAG = "tag: "
tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
if not tags:
# Either we're using git < 1.8.3, or there really are no tags. We use
# a heuristic: assume all version tags have a digit. The old git %d
# expansion behaves like git log --decorate=short and strips out the
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
# between branches and tags. By ignoring refnames without digits, we
# filter out many common branch names like "release" and
# "stabilization", as well as "HEAD" and "master".
tags = set([r for r in refs if re.search(r'\d', r)])
if verbose:
print("discarding '%s', no digits" % ",".join(refs-tags))
if verbose:
print("likely tags: %s" % ",".join(sorted(tags)))
for ref in sorted(tags):
# sorting will prefer e.g. "2.0" over "2.0rc1"
if ref.startswith(tag_prefix):
r = ref[len(tag_prefix):]
if verbose:
print("picking %s" % r)
return { "version": r,
"full": keywords["full"].strip() }
# no suitable tags, so we use the full revision id
if verbose:
print("no suitable tags, using full revision id")
return { "version": keywords["full"].strip(),
"full": keywords["full"].strip() }
def git_versions_from_vcs(tag_prefix, root, verbose=False):
# this runs 'git' from the root of the source tree. This only gets called
# if the git-archive 'subst' keywords were *not* expanded, and
# _version.py hasn't already been rewritten with a short version string,
# meaning we're inside a checked out source tree.
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %s" % root)
return {}
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"],
cwd=root)
if stdout is None:
return {}
if not stdout.startswith(tag_prefix):
if verbose:
print("tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix))
return {}
tag = stdout[len(tag_prefix):]
stdout = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
if stdout is None:
return {}
full = stdout.strip()
if tag.endswith("-dirty"):
full += "-dirty"
return {"version": tag, "full": full}
def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
# case we can only use expanded keywords.
keywords = { "refnames": git_refnames, "full": git_full }
ver = git_versions_from_keywords(keywords, tag_prefix, verbose)
if ver:
return ver
try:
root = os.path.abspath(__file__)
# versionfile_source is the relative path from the top of the source
# tree (where the .git directory might live) to this file. Invert
# this to find the root from __file__.
for i in range(len(versionfile_source.split(os.sep))):
root = os.path.dirname(root)
except NameError:
return default
return (git_versions_from_vcs(tag_prefix, root, verbose)
or versions_from_parentdir(parentdir_prefix, root, verbose)
or default)

View File

@@ -0,0 +1,53 @@
from __future__ import division
from . import der, ecdsa
class UnknownCurveError(Exception):
pass
def orderlen(order):
return (1+len("%x"%order))//2 # bytes
# the NIST curves
class Curve:
def __init__(self, name, openssl_name,
curve, generator, oid):
self.name = name
self.openssl_name = openssl_name # maybe None
self.curve = curve
self.generator = generator
self.order = generator.order()
self.baselen = orderlen(self.order)
self.verifying_key_length = 2*self.baselen
self.signature_length = 2*self.baselen
self.oid = oid
self.encoded_oid = der.encode_oid(*oid)
NIST192p = Curve("NIST192p", "prime192v1",
ecdsa.curve_192, ecdsa.generator_192,
(1, 2, 840, 10045, 3, 1, 1))
NIST224p = Curve("NIST224p", "secp224r1",
ecdsa.curve_224, ecdsa.generator_224,
(1, 3, 132, 0, 33))
NIST256p = Curve("NIST256p", "prime256v1",
ecdsa.curve_256, ecdsa.generator_256,
(1, 2, 840, 10045, 3, 1, 7))
NIST384p = Curve("NIST384p", "secp384r1",
ecdsa.curve_384, ecdsa.generator_384,
(1, 3, 132, 0, 34))
NIST521p = Curve("NIST521p", "secp521r1",
ecdsa.curve_521, ecdsa.generator_521,
(1, 3, 132, 0, 35))
SECP256k1 = Curve("SECP256k1", "secp256k1",
ecdsa.curve_secp256k1, ecdsa.generator_secp256k1,
(1, 3, 132, 0, 10))
curves = [NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1]
def find_curve(oid_curve):
for c in curves:
if c.oid == oid_curve:
return c
raise UnknownCurveError("I don't know about the curve with oid %s."
"I only know about these: %s" %
(oid_curve, [c.name for c in curves]))

199
bin/python/ecdsa/der.py Normal file
View File

@@ -0,0 +1,199 @@
from __future__ import division
import binascii
import base64
from .six import int2byte, b, integer_types, text_type
class UnexpectedDER(Exception):
pass
def encode_constructed(tag, value):
return int2byte(0xa0+tag) + encode_length(len(value)) + value
def encode_integer(r):
assert r >= 0 # can't support negative numbers yet
h = ("%x" % r).encode()
if len(h) % 2:
h = b("0") + h
s = binascii.unhexlify(h)
num = s[0] if isinstance(s[0], integer_types) else ord(s[0])
if num <= 0x7f:
return b("\x02") + int2byte(len(s)) + s
else:
# DER integers are two's complement, so if the first byte is
# 0x80-0xff then we need an extra 0x00 byte to prevent it from
# looking negative.
return b("\x02") + int2byte(len(s)+1) + b("\x00") + s
def encode_bitstring(s):
return b("\x03") + encode_length(len(s)) + s
def encode_octet_string(s):
return b("\x04") + encode_length(len(s)) + s
def encode_oid(first, second, *pieces):
assert first <= 2
assert second <= 39
encoded_pieces = [int2byte(40*first+second)] + [encode_number(p)
for p in pieces]
body = b('').join(encoded_pieces)
return b('\x06') + encode_length(len(body)) + body
def encode_sequence(*encoded_pieces):
total_len = sum([len(p) for p in encoded_pieces])
return b('\x30') + encode_length(total_len) + b('').join(encoded_pieces)
def encode_number(n):
b128_digits = []
while n:
b128_digits.insert(0, (n & 0x7f) | 0x80)
n = n >> 7
if not b128_digits:
b128_digits.append(0)
b128_digits[-1] &= 0x7f
return b('').join([int2byte(d) for d in b128_digits])
def remove_constructed(string):
s0 = string[0] if isinstance(string[0], integer_types) else ord(string[0])
if (s0 & 0xe0) != 0xa0:
raise UnexpectedDER("wanted constructed tag (0xa0-0xbf), got 0x%02x"
% s0)
tag = s0 & 0x1f
length, llen = read_length(string[1:])
body = string[1+llen:1+llen+length]
rest = string[1+llen+length:]
return tag, body, rest
def remove_sequence(string):
if not string.startswith(b("\x30")):
n = string[0] if isinstance(string[0], integer_types) else ord(string[0])
raise UnexpectedDER("wanted sequence (0x30), got 0x%02x" % n)
length, lengthlength = read_length(string[1:])
endseq = 1+lengthlength+length
return string[1+lengthlength:endseq], string[endseq:]
def remove_octet_string(string):
if not string.startswith(b("\x04")):
n = string[0] if isinstance(string[0], integer_types) else ord(string[0])
raise UnexpectedDER("wanted octetstring (0x04), got 0x%02x" % n)
length, llen = read_length(string[1:])
body = string[1+llen:1+llen+length]
rest = string[1+llen+length:]
return body, rest
def remove_object(string):
if not string.startswith(b("\x06")):
n = string[0] if isinstance(string[0], integer_types) else ord(string[0])
raise UnexpectedDER("wanted object (0x06), got 0x%02x" % n)
length, lengthlength = read_length(string[1:])
body = string[1+lengthlength:1+lengthlength+length]
rest = string[1+lengthlength+length:]
numbers = []
while body:
n, ll = read_number(body)
numbers.append(n)
body = body[ll:]
n0 = numbers.pop(0)
first = n0//40
second = n0-(40*first)
numbers.insert(0, first)
numbers.insert(1, second)
return tuple(numbers), rest
def remove_integer(string):
if not string.startswith(b("\x02")):
n = string[0] if isinstance(string[0], integer_types) else ord(string[0])
raise UnexpectedDER("wanted integer (0x02), got 0x%02x" % n)
length, llen = read_length(string[1:])
numberbytes = string[1+llen:1+llen+length]
rest = string[1+llen+length:]
nbytes = numberbytes[0] if isinstance(numberbytes[0], integer_types) else ord(numberbytes[0])
assert nbytes < 0x80 # can't support negative numbers yet
return int(binascii.hexlify(numberbytes), 16), rest
def read_number(string):
number = 0
llen = 0
# base-128 big endian, with b7 set in all but the last byte
while True:
if llen > len(string):
raise UnexpectedDER("ran out of length bytes")
number = number << 7
d = string[llen] if isinstance(string[llen], integer_types) else ord(string[llen])
number += (d & 0x7f)
llen += 1
if not d & 0x80:
break
return number, llen
def encode_length(l):
assert l >= 0
if l < 0x80:
return int2byte(l)
s = ("%x" % l).encode()
if len(s)%2:
s = b("0")+s
s = binascii.unhexlify(s)
llen = len(s)
return int2byte(0x80|llen) + s
def read_length(string):
num = string[0] if isinstance(string[0], integer_types) else ord(string[0])
if not (num & 0x80):
# short form
return (num & 0x7f), 1
# else long-form: b0&0x7f is number of additional base256 length bytes,
# big-endian
llen = num & 0x7f
if llen > len(string)-1:
raise UnexpectedDER("ran out of length bytes")
return int(binascii.hexlify(string[1:1+llen]), 16), 1+llen
def remove_bitstring(string):
num = string[0] if isinstance(string[0], integer_types) else ord(string[0])
if not string.startswith(b("\x03")):
raise UnexpectedDER("wanted bitstring (0x03), got 0x%02x" % num)
length, llen = read_length(string[1:])
body = string[1+llen:1+llen+length]
rest = string[1+llen+length:]
return body, rest
# SEQUENCE([1, STRING(secexp), cont[0], OBJECT(curvename), cont[1], BINTSTRING)
# signatures: (from RFC3279)
# ansi-X9-62 OBJECT IDENTIFIER ::= {
# iso(1) member-body(2) us(840) 10045 }
#
# id-ecSigType OBJECT IDENTIFIER ::= {
# ansi-X9-62 signatures(4) }
# ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
# id-ecSigType 1 }
## so 1,2,840,10045,4,1
## so 0x42, .. ..
# Ecdsa-Sig-Value ::= SEQUENCE {
# r INTEGER,
# s INTEGER }
# id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 }
#
# id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
# I think the secp224r1 identifier is (t=06,l=05,v=2b81040021)
# secp224r1 OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) curve(0) 33 }
# and the secp384r1 is (t=06,l=05,v=2b81040022)
# secp384r1 OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) curve(0) 34 }
def unpem(pem):
if isinstance(pem, text_type):
pem = pem.encode()
d = b("").join([l.strip() for l in pem.split(b("\n"))
if l and not l.startswith(b("-----"))])
return base64.b64decode(d)
def topem(der, name):
b64 = base64.b64encode(der)
lines = [("-----BEGIN %s-----\n" % name).encode()]
lines.extend([b64[start:start+64]+b("\n")
for start in range(0, len(b64), 64)])
lines.append(("-----END %s-----\n" % name).encode())
return b("").join(lines)

576
bin/python/ecdsa/ecdsa.py Normal file
View File

@@ -0,0 +1,576 @@
#! /usr/bin/env python
"""
Implementation of Elliptic-Curve Digital Signatures.
Classes and methods for elliptic-curve signatures:
private keys, public keys, signatures,
NIST prime-modulus curves with modulus lengths of
192, 224, 256, 384, and 521 bits.
Example:
# (In real-life applications, you would probably want to
# protect against defects in SystemRandom.)
from random import SystemRandom
randrange = SystemRandom().randrange
# Generate a public/private key pair using the NIST Curve P-192:
g = generator_192
n = g.order()
secret = randrange( 1, n )
pubkey = Public_key( g, g * secret )
privkey = Private_key( pubkey, secret )
# Signing a hash value:
hash = randrange( 1, n )
signature = privkey.sign( hash, randrange( 1, n ) )
# Verifying a signature for a hash value:
if pubkey.verifies( hash, signature ):
print_("Demo verification succeeded.")
else:
print_("*** Demo verification failed.")
# Verification fails if the hash value is modified:
if pubkey.verifies( hash-1, signature ):
print_("**** Demo verification failed to reject tampered hash.")
else:
print_("Demo verification correctly rejected tampered hash.")
Version of 2009.05.16.
Revision history:
2005.12.31 - Initial version.
2008.11.25 - Substantial revisions introducing new classes.
2009.05.16 - Warn against using random.randrange in real applications.
2009.05.17 - Use random.SystemRandom by default.
Written in 2005 by Peter Pearson and placed in the public domain.
"""
from .six import int2byte, b, print_
from . import ellipticcurve
from . import numbertheory
import random
class Signature( object ):
"""ECDSA signature.
"""
def __init__( self, r, s ):
self.r = r
self.s = s
class Public_key( object ):
"""Public key for ECDSA.
"""
def __init__( self, generator, point ):
"""generator is the Point that generates the group,
point is the Point that defines the public key.
"""
self.curve = generator.curve()
self.generator = generator
self.point = point
n = generator.order()
if not n:
raise RuntimeError("Generator point must have order.")
if not n * point == ellipticcurve.INFINITY:
raise RuntimeError("Generator point order is bad.")
if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
raise RuntimeError("Generator point has x or y out of range.")
def verifies( self, hash, signature ):
"""Verify that signature is a valid signature of hash.
Return True if the signature is valid.
"""
# From X9.62 J.3.1.
G = self.generator
n = G.order()
r = signature.r
s = signature.s
if r < 1 or r > n-1: return False
if s < 1 or s > n-1: return False
c = numbertheory.inverse_mod( s, n )
u1 = ( hash * c ) % n
u2 = ( r * c ) % n
xy = u1 * G + u2 * self.point
v = xy.x() % n
return v == r
class Private_key( object ):
"""Private key for ECDSA.
"""
def __init__( self, public_key, secret_multiplier ):
"""public_key is of class Public_key;
secret_multiplier is a large integer.
"""
self.public_key = public_key
self.secret_multiplier = secret_multiplier
def sign( self, hash, random_k ):
"""Return a signature for the provided hash, using the provided
random nonce. It is absolutely vital that random_k be an unpredictable
number in the range [1, self.public_key.point.order()-1]. If
an attacker can guess random_k, he can compute our private key from a
single signature. Also, if an attacker knows a few high-order
bits (or a few low-order bits) of random_k, he can compute our private
key from many signatures. The generation of nonces with adequate
cryptographic strength is very difficult and far beyond the scope
of this comment.
May raise RuntimeError, in which case retrying with a new
random value k is in order.
"""
G = self.public_key.generator
n = G.order()
k = random_k % n
p1 = k * G
r = p1.x()
if r == 0: raise RuntimeError("amazingly unlucky random number r")
s = ( numbertheory.inverse_mod( k, n ) * \
( hash + ( self.secret_multiplier * r ) % n ) ) % n
if s == 0: raise RuntimeError("amazingly unlucky random number s")
return Signature( r, s )
def int_to_string( x ):
"""Convert integer x into a string of bytes, as per X9.62."""
assert x >= 0
if x == 0: return b('\0')
result = []
while x:
ordinal = x & 0xFF
result.append(int2byte(ordinal))
x >>= 8
result.reverse()
return b('').join(result)
def string_to_int( s ):
"""Convert a string of bytes into an integer, as per X9.62."""
result = 0
for c in s:
if not isinstance(c, int): c = ord( c )
result = 256 * result + c
return result
def digest_integer( m ):
"""Convert an integer into a string of bytes, compute
its SHA-1 hash, and convert the result to an integer."""
#
# I don't expect this function to be used much. I wrote
# it in order to be able to duplicate the examples
# in ECDSAVS.
#
from hashlib import sha1
return string_to_int( sha1( int_to_string( m ) ).digest() )
def point_is_valid( generator, x, y ):
"""Is (x,y) a valid public key based on the specified generator?"""
# These are the tests specified in X9.62.
n = generator.order()
curve = generator.curve()
if x < 0 or n <= x or y < 0 or n <= y:
return False
if not curve.contains_point( x, y ):
return False
if not n*ellipticcurve.Point( curve, x, y ) == \
ellipticcurve.INFINITY:
return False
return True
# NIST Curve P-192:
_p = 6277101735386680763835789423207666416083908700390324961279
_r = 6277101735386680763835789423176059013767194773182842284081
# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L
_b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
_Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
_Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
curve_192 = ellipticcurve.CurveFp( _p, -3, _b )
generator_192 = ellipticcurve.Point( curve_192, _Gx, _Gy, _r )
# NIST Curve P-224:
_p = 26959946667150639794667015087019630673557916260026308143510066298881
_r = 26959946667150639794667015087019625940457807714424391721682722368061
# s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L
# c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL
_b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
_Gx =0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
_Gy = 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34
curve_224 = ellipticcurve.CurveFp( _p, -3, _b )
generator_224 = ellipticcurve.Point( curve_224, _Gx, _Gy, _r )
# NIST Curve P-256:
_p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
_r = 115792089210356248762697446949407573529996955224135760342422259061068512044369
# s = 0xc49d360886e704936a6678e1139d26b7819f7e90L
# c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL
_b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
_Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
_Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
curve_256 = ellipticcurve.CurveFp( _p, -3, _b )
generator_256 = ellipticcurve.Point( curve_256, _Gx, _Gy, _r )
# NIST Curve P-384:
_p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319
_r = 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
# s = 0xa335926aa319a27a1d00896a6773a4827acdac73L
# c = 0x79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483L
_b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
_Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7
_Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f
curve_384 = ellipticcurve.CurveFp( _p, -3, _b )
generator_384 = ellipticcurve.Point( curve_384, _Gx, _Gy, _r )
# NIST Curve P-521:
_p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151
_r = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449
# s = 0xd09e8800291cb85396cc6717393284aaa0da64baL
# c = 0x0b48bfa5f420a34949539d2bdfc264eeeeb077688e44fbf0ad8f6d0edb37bd6b533281000518e19f1b9ffbe0fe9ed8a3c2200b8f875e523868c70c1e5bf55bad637L
_b = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
_Gx = 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
_Gy = 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
curve_521 = ellipticcurve.CurveFp( _p, -3, _b )
generator_521 = ellipticcurve.Point( curve_521, _Gx, _Gy, _r )
# Certicom secp256-k1
_a = 0x0000000000000000000000000000000000000000000000000000000000000000
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
_p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
_Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
_r = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
curve_secp256k1 = ellipticcurve.CurveFp( _p, _a, _b)
generator_secp256k1 = ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r)
def __main__():
class TestFailure(Exception): pass
def test_point_validity( generator, x, y, expected ):
"""generator defines the curve; is (x,y) a point on
this curve? "expected" is True if the right answer is Yes."""
if point_is_valid( generator, x, y ) == expected:
print_("Point validity tested as expected.")
else:
raise TestFailure("*** Point validity test gave wrong result.")
def test_signature_validity( Msg, Qx, Qy, R, S, expected ):
"""Msg = message, Qx and Qy represent the base point on
elliptic curve c192, R and S are the signature, and
"expected" is True iff the signature is expected to be valid."""
pubk = Public_key( generator_192,
ellipticcurve.Point( curve_192, Qx, Qy ) )
got = pubk.verifies( digest_integer( Msg ), Signature( R, S ) )
if got == expected:
print_("Signature tested as expected: got %s, expected %s." % \
( got, expected ))
else:
raise TestFailure("*** Signature test failed: got %s, expected %s." % \
( got, expected ))
print_("NIST Curve P-192:")
p192 = generator_192
# From X9.62:
d = 651056770906015076056810763456358567190100156695615665659
Q = d * p192
if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5:
raise TestFailure("*** p192 * d came out wrong.")
else:
print_("p192 * d came out right.")
k = 6140507067065001063065065565667405560006161556565665656654
R = k * p192
if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
raise TestFailure("*** k * p192 came out wrong.")
else:
print_("k * p192 came out right.")
u1 = 2563697409189434185194736134579731015366492496392189760599
u2 = 6266643813348617967186477710235785849136406323338782220568
temp = u1 * p192 + u2 * Q
if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
raise TestFailure("*** u1 * p192 + u2 * Q came out wrong.")
else:
print_("u1 * p192 + u2 * Q came out right.")
e = 968236873715988614170569073515315707566766479517
pubk = Public_key( generator_192, generator_192 * d )
privk = Private_key( pubk, d )
sig = privk.sign( e, k )
r, s = sig.r, sig.s
if r != 3342403536405981729393488334694600415596881826869351677613 \
or s != 5735822328888155254683894997897571951568553642892029982342:
raise TestFailure("*** r or s came out wrong.")
else:
print_("r and s came out right.")
valid = pubk.verifies( e, sig )
if valid: print_("Signature verified OK.")
else: raise TestFailure("*** Signature failed verification.")
valid = pubk.verifies( e-1, sig )
if not valid: print_("Forgery was correctly rejected.")
else: raise TestFailure("*** Forgery was erroneously accepted.")
print_("Testing point validity, as per ECDSAVS.pdf B.2.2:")
test_point_validity( \
p192, \
0xcd6d0f029a023e9aaca429615b8f577abee685d8257cc83a, \
0x00019c410987680e9fb6c0b6ecc01d9a2647c8bae27721bacdfc, \
False )
test_point_validity(
p192, \
0x00017f2fce203639e9eaf9fb50b81fc32776b30e3b02af16c73b, \
0x95da95c5e72dd48e229d4748d4eee658a9a54111b23b2adb, \
False )
test_point_validity(
p192, \
0x4f77f8bc7fccbadd5760f4938746d5f253ee2168c1cf2792, \
0x000147156ff824d131629739817edb197717c41aab5c2a70f0f6, \
False )
test_point_validity(
p192, \
0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6, \
0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f, \
True )
test_point_validity(
p192, \
0xcdf56c1aa3d8afc53c521adf3ffb96734a6a630a4a5b5a70, \
0x97c1c44a5fb229007b5ec5d25f7413d170068ffd023caa4e, \
True )
test_point_validity(
p192, \
0x89009c0dc361c81e99280c8e91df578df88cdf4b0cdedced, \
0x27be44a529b7513e727251f128b34262a0fd4d8ec82377b9, \
True )
test_point_validity(
p192, \
0x6a223d00bd22c52833409a163e057e5b5da1def2a197dd15, \
0x7b482604199367f1f303f9ef627f922f97023e90eae08abf, \
True )
test_point_validity(
p192, \
0x6dccbde75c0948c98dab32ea0bc59fe125cf0fb1a3798eda, \
0x0001171a3e0fa60cf3096f4e116b556198de430e1fbd330c8835, \
False )
test_point_validity(
p192, \
0xd266b39e1f491fc4acbbbc7d098430931cfa66d55015af12, \
0x193782eb909e391a3148b7764e6b234aa94e48d30a16dbb2, \
False )
test_point_validity(
p192, \
0x9d6ddbcd439baa0c6b80a654091680e462a7d1d3f1ffeb43, \
0x6ad8efc4d133ccf167c44eb4691c80abffb9f82b932b8caa, \
False )
test_point_validity(
p192, \
0x146479d944e6bda87e5b35818aa666a4c998a71f4e95edbc, \
0xa86d6fe62bc8fbd88139693f842635f687f132255858e7f6, \
False )
test_point_validity(
p192, \
0xe594d4a598046f3598243f50fd2c7bd7d380edb055802253, \
0x509014c0c4d6b536e3ca750ec09066af39b4c8616a53a923, \
False )
print_("Trying signature-verification tests from ECDSAVS.pdf B.2.4:")
print_("P-192:")
Msg = 0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff798cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d158
Qx = 0xd9dbfb332aa8e5ff091e8ce535857c37c73f6250ffb2e7ac
Qy = 0x282102e364feded3ad15ddf968f88d8321aa268dd483ebc4
R = 0x64dca58a20787c488d11d6dd96313f1b766f2d8efe122916
S = 0x1ecba28141e84ab4ecad92f56720e2cc83eb3d22dec72479
test_signature_validity( Msg, Qx, Qy, R, S, True )
Msg = 0x94bb5bacd5f8ea765810024db87f4224ad71362a3c28284b2b9f39fab86db12e8beb94aae899768229be8fdb6c4f12f28912bb604703a79ccff769c1607f5a91450f30ba0460d359d9126cbd6296be6d9c4bb96c0ee74cbb44197c207f6db326ab6f5a659113a9034e54be7b041ced9dcf6458d7fb9cbfb2744d999f7dfd63f4
Qx = 0x3e53ef8d3112af3285c0e74842090712cd324832d4277ae7
Qy = 0xcc75f8952d30aec2cbb719fc6aa9934590b5d0ff5a83adb7
R = 0x8285261607283ba18f335026130bab31840dcfd9c3e555af
S = 0x356d89e1b04541afc9704a45e9c535ce4a50929e33d7e06c
test_signature_validity( Msg, Qx, Qy, R, S, True )
Msg = 0xf6227a8eeb34afed1621dcc89a91d72ea212cb2f476839d9b4243c66877911b37b4ad6f4448792a7bbba76c63bdd63414b6facab7dc71c3396a73bd7ee14cdd41a659c61c99b779cecf07bc51ab391aa3252386242b9853ea7da67fd768d303f1b9b513d401565b6f1eb722dfdb96b519fe4f9bd5de67ae131e64b40e78c42dd
Qx = 0x16335dbe95f8e8254a4e04575d736befb258b8657f773cb7
Qy = 0x421b13379c59bc9dce38a1099ca79bbd06d647c7f6242336
R = 0x4141bd5d64ea36c5b0bd21ef28c02da216ed9d04522b1e91
S = 0x159a6aa852bcc579e821b7bb0994c0861fb08280c38daa09
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x16b5f93afd0d02246f662761ed8e0dd9504681ed02a253006eb36736b563097ba39f81c8e1bce7a16c1339e345efabbc6baa3efb0612948ae51103382a8ee8bc448e3ef71e9f6f7a9676694831d7f5dd0db5446f179bcb737d4a526367a447bfe2c857521c7f40b6d7d7e01a180d92431fb0bbd29c04a0c420a57b3ed26ccd8a
Qx = 0xfd14cdf1607f5efb7b1793037b15bdf4baa6f7c16341ab0b
Qy = 0x83fa0795cc6c4795b9016dac928fd6bac32f3229a96312c4
R = 0x8dfdb832951e0167c5d762a473c0416c5c15bc1195667dc1
S = 0x1720288a2dc13fa1ec78f763f8fe2ff7354a7e6fdde44520
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x08a2024b61b79d260e3bb43ef15659aec89e5b560199bc82cf7c65c77d39192e03b9a895d766655105edd9188242b91fbde4167f7862d4ddd61e5d4ab55196683d4f13ceb90d87aea6e07eb50a874e33086c4a7cb0273a8e1c4408f4b846bceae1ebaac1b2b2ea851a9b09de322efe34cebe601653efd6ddc876ce8c2f2072fb
Qx = 0x674f941dc1a1f8b763c9334d726172d527b90ca324db8828
Qy = 0x65adfa32e8b236cb33a3e84cf59bfb9417ae7e8ede57a7ff
R = 0x9508b9fdd7daf0d8126f9e2bc5a35e4c6d800b5b804d7796
S = 0x36f2bf6b21b987c77b53bb801b3435a577e3d493744bfab0
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x1843aba74b0789d4ac6b0b8923848023a644a7b70afa23b1191829bbe4397ce15b629bf21a8838298653ed0c19222b95fa4f7390d1b4c844d96e645537e0aae98afb5c0ac3bd0e4c37f8daaff25556c64e98c319c52687c904c4de7240a1cc55cd9756b7edaef184e6e23b385726e9ffcba8001b8f574987c1a3fedaaa83ca6d
Qx = 0x10ecca1aad7220b56a62008b35170bfd5e35885c4014a19f
Qy = 0x04eb61984c6c12ade3bc47f3c629ece7aa0a033b9948d686
R = 0x82bfa4e82c0dfe9274169b86694e76ce993fd83b5c60f325
S = 0xa97685676c59a65dbde002fe9d613431fb183e8006d05633
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x5a478f4084ddd1a7fea038aa9732a822106385797d02311aeef4d0264f824f698df7a48cfb6b578cf3da416bc0799425bb491be5b5ecc37995b85b03420a98f2c4dc5c31a69a379e9e322fbe706bbcaf0f77175e05cbb4fa162e0da82010a278461e3e974d137bc746d1880d6eb02aa95216014b37480d84b87f717bb13f76e1
Qx = 0x6636653cb5b894ca65c448277b29da3ad101c4c2300f7c04
Qy = 0xfdf1cbb3fc3fd6a4f890b59e554544175fa77dbdbeb656c1
R = 0xeac2ddecddfb79931a9c3d49c08de0645c783a24cb365e1c
S = 0x3549fee3cfa7e5f93bc47d92d8ba100e881a2a93c22f8d50
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0xc598774259a058fa65212ac57eaa4f52240e629ef4c310722088292d1d4af6c39b49ce06ba77e4247b20637174d0bd67c9723feb57b5ead232b47ea452d5d7a089f17c00b8b6767e434a5e16c231ba0efa718a340bf41d67ea2d295812ff1b9277daacb8bc27b50ea5e6443bcf95ef4e9f5468fe78485236313d53d1c68f6ba2
Qx = 0xa82bd718d01d354001148cd5f69b9ebf38ff6f21898f8aaa
Qy = 0xe67ceede07fc2ebfafd62462a51e4b6c6b3d5b537b7caf3e
R = 0x4d292486c620c3de20856e57d3bb72fcde4a73ad26376955
S = 0xa85289591a6081d5728825520e62ff1c64f94235c04c7f95
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0xca98ed9db081a07b7557f24ced6c7b9891269a95d2026747add9e9eb80638a961cf9c71a1b9f2c29744180bd4c3d3db60f2243c5c0b7cc8a8d40a3f9a7fc910250f2187136ee6413ffc67f1a25e1c4c204fa9635312252ac0e0481d89b6d53808f0c496ba87631803f6c572c1f61fa049737fdacce4adff757afed4f05beb658
Qx = 0x7d3b016b57758b160c4fca73d48df07ae3b6b30225126c2f
Qy = 0x4af3790d9775742bde46f8da876711be1b65244b2b39e7ec
R = 0x95f778f5f656511a5ab49a5d69ddd0929563c29cbc3a9e62
S = 0x75c87fc358c251b4c83d2dd979faad496b539f9f2ee7a289
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x31dd9a54c8338bea06b87eca813d555ad1850fac9742ef0bbe40dad400e10288acc9c11ea7dac79eb16378ebea9490e09536099f1b993e2653cd50240014c90a9c987f64545abc6a536b9bd2435eb5e911fdfde2f13be96ea36ad38df4ae9ea387b29cced599af777338af2794820c9cce43b51d2112380a35802ab7e396c97a
Qx = 0x9362f28c4ef96453d8a2f849f21e881cd7566887da8beb4a
Qy = 0xe64d26d8d74c48a024ae85d982ee74cd16046f4ee5333905
R = 0xf3923476a296c88287e8de914b0b324ad5a963319a4fe73b
S = 0xf0baeed7624ed00d15244d8ba2aede085517dbdec8ac65f5
test_signature_validity( Msg, Qx, Qy, R, S, True )
Msg = 0xb2b94e4432267c92f9fdb9dc6040c95ffa477652761290d3c7de312283f6450d89cc4aabe748554dfb6056b2d8e99c7aeaad9cdddebdee9dbc099839562d9064e68e7bb5f3a6bba0749ca9a538181fc785553a4000785d73cc207922f63e8ce1112768cb1de7b673aed83a1e4a74592f1268d8e2a4e9e63d414b5d442bd0456d
Qx = 0xcc6fc032a846aaac25533eb033522824f94e670fa997ecef
Qy = 0xe25463ef77a029eccda8b294fd63dd694e38d223d30862f1
R = 0x066b1d07f3a40e679b620eda7f550842a35c18b80c5ebe06
S = 0xa0b0fb201e8f2df65e2c4508ef303bdc90d934016f16b2dc
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x4366fcadf10d30d086911de30143da6f579527036937007b337f7282460eae5678b15cccda853193ea5fc4bc0a6b9d7a31128f27e1214988592827520b214eed5052f7775b750b0c6b15f145453ba3fee24a085d65287e10509eb5d5f602c440341376b95c24e5c4727d4b859bfe1483d20538acdd92c7997fa9c614f0f839d7
Qx = 0x955c908fe900a996f7e2089bee2f6376830f76a19135e753
Qy = 0xba0c42a91d3847de4a592a46dc3fdaf45a7cc709b90de520
R = 0x1f58ad77fc04c782815a1405b0925e72095d906cbf52a668
S = 0xf2e93758b3af75edf784f05a6761c9b9a6043c66b845b599
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x543f8af57d750e33aa8565e0cae92bfa7a1ff78833093421c2942cadf9986670a5ff3244c02a8225e790fbf30ea84c74720abf99cfd10d02d34377c3d3b41269bea763384f372bb786b5846f58932defa68023136cd571863b304886e95e52e7877f445b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3c87da160cef3
Qx = 0x31f7fa05576d78a949b24812d4383107a9a45bb5fccdd835
Qy = 0x8dc0eb65994a90f02b5e19bd18b32d61150746c09107e76b
R = 0xbe26d59e4e883dde7c286614a767b31e49ad88789d3a78ff
S = 0x8762ca831c1ce42df77893c9b03119428e7a9b819b619068
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0xd2e8454143ce281e609a9d748014dcebb9d0bc53adb02443a6aac2ffe6cb009f387c346ecb051791404f79e902ee333ad65e5c8cb38dc0d1d39a8dc90add5023572720e5b94b190d43dd0d7873397504c0c7aef2727e628eb6a74411f2e400c65670716cb4a815dc91cbbfeb7cfe8c929e93184c938af2c078584da045e8f8d1
Qx = 0x66aa8edbbdb5cf8e28ceb51b5bda891cae2df84819fe25c0
Qy = 0x0c6bc2f69030a7ce58d4a00e3b3349844784a13b8936f8da
R = 0xa4661e69b1734f4a71b788410a464b71e7ffe42334484f23
S = 0x738421cf5e049159d69c57a915143e226cac8355e149afe9
test_signature_validity( Msg, Qx, Qy, R, S, False )
Msg = 0x6660717144040f3e2f95a4e25b08a7079c702a8b29babad5a19a87654bc5c5afa261512a11b998a4fb36b5d8fe8bd942792ff0324b108120de86d63f65855e5461184fc96a0a8ffd2ce6d5dfb0230cbbdd98f8543e361b3205f5da3d500fdc8bac6db377d75ebef3cb8f4d1ff738071ad0938917889250b41dd1d98896ca06fb
Qx = 0xbcfacf45139b6f5f690a4c35a5fffa498794136a2353fc77
Qy = 0x6f4a6c906316a6afc6d98fe1f0399d056f128fe0270b0f22
R = 0x9db679a3dafe48f7ccad122933acfe9da0970b71c94c21c1
S = 0x984c2db99827576c0a41a5da41e07d8cc768bc82f18c9da9
test_signature_validity( Msg, Qx, Qy, R, S, False )
print_("Testing the example code:")
# Building a public/private key pair from the NIST Curve P-192:
g = generator_192
n = g.order()
# (random.SystemRandom is supposed to provide
# crypto-quality random numbers, but as Debian recently
# illustrated, a systems programmer can accidentally
# demolish this security, so in serious applications
# further precautions are appropriate.)
randrange = random.SystemRandom().randrange
secret = randrange( 1, n )
pubkey = Public_key( g, g * secret )
privkey = Private_key( pubkey, secret )
# Signing a hash value:
hash = randrange( 1, n )
signature = privkey.sign( hash, randrange( 1, n ) )
# Verifying a signature for a hash value:
if pubkey.verifies( hash, signature ):
print_("Demo verification succeeded.")
else:
raise TestFailure("*** Demo verification failed.")
if pubkey.verifies( hash-1, signature ):
raise TestFailure( "**** Demo verification failed to reject tampered hash.")
else:
print_("Demo verification correctly rejected tampered hash.")
if __name__ == "__main__":
__main__()

View File

@@ -0,0 +1,293 @@
#! /usr/bin/env python
#
# Implementation of elliptic curves, for cryptographic applications.
#
# This module doesn't provide any way to choose a random elliptic
# curve, nor to verify that an elliptic curve was chosen randomly,
# because one can simply use NIST's standard curves.
#
# Notes from X9.62-1998 (draft):
# Nomenclature:
# - Q is a public key.
# The "Elliptic Curve Domain Parameters" include:
# - q is the "field size", which in our case equals p.
# - p is a big prime.
# - G is a point of prime order (5.1.1.1).
# - n is the order of G (5.1.1.1).
# Public-key validation (5.2.2):
# - Verify that Q is not the point at infinity.
# - Verify that X_Q and Y_Q are in [0,p-1].
# - Verify that Q is on the curve.
# - Verify that nQ is the point at infinity.
# Signature generation (5.3):
# - Pick random k from [1,n-1].
# Signature checking (5.4.2):
# - Verify that r and s are in [1,n-1].
#
# Version of 2008.11.25.
#
# Revision history:
# 2005.12.31 - Initial version.
# 2008.11.25 - Change CurveFp.is_on to contains_point.
#
# Written in 2005 by Peter Pearson and placed in the public domain.
from __future__ import division
from .six import print_
from . import numbertheory
class CurveFp( object ):
"""Elliptic Curve over the field of integers modulo a prime."""
def __init__( self, p, a, b ):
"""The curve of points satisfying y^2 = x^3 + a*x + b (mod p)."""
self.__p = p
self.__a = a
self.__b = b
def p( self ):
return self.__p
def a( self ):
return self.__a
def b( self ):
return self.__b
def contains_point( self, x, y ):
"""Is the point (x,y) on this curve?"""
return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
class Point( object ):
"""A point on an elliptic curve. Altering x and y is forbidding,
but they can be read by the x() and y() methods."""
def __init__( self, curve, x, y, order = None ):
"""curve, x, y, order; order (optional) is the order of this point."""
self.__curve = curve
self.__x = x
self.__y = y
self.__order = order
# self.curve is allowed to be None only for INFINITY:
if self.__curve: assert self.__curve.contains_point( x, y )
if order: assert self * order == INFINITY
def __eq__( self, other ):
"""Return True if the points are identical, False otherwise."""
if self.__curve == other.__curve \
and self.__x == other.__x \
and self.__y == other.__y:
return True
else:
return False
def __add__( self, other ):
"""Add one point to another point."""
# X9.62 B.3:
if other == INFINITY: return self
if self == INFINITY: return other
assert self.__curve == other.__curve
if self.__x == other.__x:
if ( self.__y + other.__y ) % self.__curve.p() == 0:
return INFINITY
else:
return self.double()
p = self.__curve.p()
l = ( ( other.__y - self.__y ) * \
numbertheory.inverse_mod( other.__x - self.__x, p ) ) % p
x3 = ( l * l - self.__x - other.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def __mul__( self, other ):
"""Multiply a point by an integer."""
def leftmost_bit( x ):
assert x > 0
result = 1
while result <= x: result = 2 * result
return result // 2
e = other
if self.__order: e = e % self.__order
if e == 0: return INFINITY
if self == INFINITY: return INFINITY
assert e > 0
# From X9.62 D.3.2:
e3 = 3 * e
negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
i = leftmost_bit( e3 ) // 2
result = self
# print_("Multiplying %s by %d (e3 = %d):" % ( self, other, e3 ))
while i > 1:
result = result.double()
if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
# print_(". . . i = %d, result = %s" % ( i, result ))
i = i // 2
return result
def __rmul__( self, other ):
"""Multiply a point by an integer."""
return self * other
def __str__( self ):
if self == INFINITY: return "infinity"
return "(%d,%d)" % ( self.__x, self.__y )
def double( self ):
"""Return a new point that is twice the old."""
if self == INFINITY:
return INFINITY
# X9.62 B.3:
p = self.__curve.p()
a = self.__curve.a()
l = ( ( 3 * self.__x * self.__x + a ) * \
numbertheory.inverse_mod( 2 * self.__y, p ) ) % p
x3 = ( l * l - 2 * self.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def x( self ):
return self.__x
def y( self ):
return self.__y
def curve( self ):
return self.__curve
def order( self ):
return self.__order
# This one point is the Point At Infinity for all purposes:
INFINITY = Point( None, None, None )
def __main__():
class FailedTest(Exception): pass
def test_add( c, x1, y1, x2, y2, x3, y3 ):
"""We expect that on curve c, (x1,y1) + (x2, y2 ) = (x3, y3)."""
p1 = Point( c, x1, y1 )
p2 = Point( c, x2, y2 )
p3 = p1 + p2
print_("%s + %s = %s" % ( p1, p2, p3 ), end=' ')
if p3.x() != x3 or p3.y() != y3:
raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
else:
print_(" Good.")
def test_double( c, x1, y1, x3, y3 ):
"""We expect that on curve c, 2*(x1,y1) = (x3, y3)."""
p1 = Point( c, x1, y1 )
p3 = p1.double()
print_("%s doubled = %s" % ( p1, p3 ), end=' ')
if p3.x() != x3 or p3.y() != y3:
raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
else:
print_(" Good.")
def test_double_infinity( c ):
"""We expect that on curve c, 2*INFINITY = INFINITY."""
p1 = INFINITY
p3 = p1.double()
print_("%s doubled = %s" % ( p1, p3 ), end=' ')
if p3.x() != INFINITY.x() or p3.y() != INFINITY.y():
raise FailedTest("Failure: should give (%d,%d)." % ( INFINITY.x(), INFINITY.y() ))
else:
print_(" Good.")
def test_multiply( c, x1, y1, m, x3, y3 ):
"""We expect that on curve c, m*(x1,y1) = (x3,y3)."""
p1 = Point( c, x1, y1 )
p3 = p1 * m
print_("%s * %d = %s" % ( p1, m, p3 ), end=' ')
if p3.x() != x3 or p3.y() != y3:
raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 ))
else:
print_(" Good.")
# A few tests from X9.62 B.3:
c = CurveFp( 23, 1, 1 )
test_add( c, 3, 10, 9, 7, 17, 20 )
test_double( c, 3, 10, 7, 12 )
test_add( c, 3, 10, 3, 10, 7, 12 ) # (Should just invoke double.)
test_multiply( c, 3, 10, 2, 7, 12 )
test_double_infinity(c)
# From X9.62 I.1 (p. 96):
g = Point( c, 13, 7, 7 )
check = INFINITY
for i in range( 7 + 1 ):
p = ( i % 7 ) * g
print_("%s * %d = %s, expected %s . . ." % ( g, i, p, check ), end=' ')
if p == check:
print_(" Good.")
else:
raise FailedTest("Bad.")
check = check + g
# NIST Curve P-192:
p = 6277101735386680763835789423207666416083908700390324961279
r = 6277101735386680763835789423176059013767194773182842284081
#s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65
b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
c192 = CurveFp( p, -3, b )
p192 = Point( c192, Gx, Gy, r )
# Checking against some sample computations presented
# in X9.62:
d = 651056770906015076056810763456358567190100156695615665659
Q = d * p192
if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5:
raise FailedTest("p192 * d came out wrong.")
else:
print_("p192 * d came out right.")
k = 6140507067065001063065065565667405560006161556565665656654
R = k * p192
if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
raise FailedTest("k * p192 came out wrong.")
else:
print_("k * p192 came out right.")
u1 = 2563697409189434185194736134579731015366492496392189760599
u2 = 6266643813348617967186477710235785849136406323338782220568
temp = u1 * p192 + u2 * Q
if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \
or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835:
raise FailedTest("u1 * p192 + u2 * Q came out wrong.")
else:
print_("u1 * p192 + u2 * Q came out right.")
if __name__ == "__main__":
__main__()

283
bin/python/ecdsa/keys.py Normal file
View File

@@ -0,0 +1,283 @@
import binascii
from . import ecdsa
from . import der
from . import rfc6979
from .curves import NIST192p, find_curve
from .util import string_to_number, number_to_string, randrange
from .util import sigencode_string, sigdecode_string
from .util import oid_ecPublicKey, encoded_oid_ecPublicKey
from .six import PY3, b
from hashlib import sha1
class BadSignatureError(Exception):
pass
class BadDigestError(Exception):
pass
class VerifyingKey:
def __init__(self, _error__please_use_generate=None):
if not _error__please_use_generate:
raise TypeError("Please use SigningKey.generate() to construct me")
@classmethod
def from_public_point(klass, point, curve=NIST192p, hashfunc=sha1):
self = klass(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = hashfunc
self.pubkey = ecdsa.Public_key(curve.generator, point)
self.pubkey.order = curve.order
return self
@classmethod
def from_string(klass, string, curve=NIST192p, hashfunc=sha1,
validate_point=True):
order = curve.order
assert len(string) == curve.verifying_key_length, \
(len(string), curve.verifying_key_length)
xs = string[:curve.baselen]
ys = string[curve.baselen:]
assert len(xs) == curve.baselen, (len(xs), curve.baselen)
assert len(ys) == curve.baselen, (len(ys), curve.baselen)
x = string_to_number(xs)
y = string_to_number(ys)
if validate_point:
assert ecdsa.point_is_valid(curve.generator, x, y)
from . import ellipticcurve
point = ellipticcurve.Point(curve.curve, x, y, order)
return klass.from_public_point(point, curve, hashfunc)
@classmethod
def from_pem(klass, string):
return klass.from_der(der.unpem(string))
@classmethod
def from_der(klass, string):
# [[oid_ecPublicKey,oid_curve], point_str_bitstring]
s1,empty = der.remove_sequence(string)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER pubkey: %s" %
binascii.hexlify(empty))
s2,point_str_bitstring = der.remove_sequence(s1)
# s2 = oid_ecPublicKey,oid_curve
oid_pk, rest = der.remove_object(s2)
oid_curve, empty = der.remove_object(rest)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER pubkey objects: %s" %
binascii.hexlify(empty))
assert oid_pk == oid_ecPublicKey, (oid_pk, oid_ecPublicKey)
curve = find_curve(oid_curve)
point_str, empty = der.remove_bitstring(point_str_bitstring)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after pubkey pointstring: %s" %
binascii.hexlify(empty))
assert point_str.startswith(b("\x00\x04"))
return klass.from_string(point_str[2:], curve)
def to_string(self):
# VerifyingKey.from_string(vk.to_string()) == vk as long as the
# curves are the same: the curve itself is not included in the
# serialized form
order = self.pubkey.order
x_str = number_to_string(self.pubkey.point.x(), order)
y_str = number_to_string(self.pubkey.point.y(), order)
return x_str + y_str
def to_pem(self):
return der.topem(self.to_der(), "PUBLIC KEY")
def to_der(self):
order = self.pubkey.order
x_str = number_to_string(self.pubkey.point.x(), order)
y_str = number_to_string(self.pubkey.point.y(), order)
point_str = b("\x00\x04") + x_str + y_str
return der.encode_sequence(der.encode_sequence(encoded_oid_ecPublicKey,
self.curve.encoded_oid),
der.encode_bitstring(point_str))
def verify(self, signature, data, hashfunc=None, sigdecode=sigdecode_string):
hashfunc = hashfunc or self.default_hashfunc
digest = hashfunc(data).digest()
return self.verify_digest(signature, digest, sigdecode)
def verify_digest(self, signature, digest, sigdecode=sigdecode_string):
if len(digest) > self.curve.baselen:
raise BadDigestError("this curve (%s) is too short "
"for your digest (%d)" % (self.curve.name,
8*len(digest)))
number = string_to_number(digest)
r, s = sigdecode(signature, self.pubkey.order)
sig = ecdsa.Signature(r, s)
if self.pubkey.verifies(number, sig):
return True
raise BadSignatureError
class SigningKey:
def __init__(self, _error__please_use_generate=None):
if not _error__please_use_generate:
raise TypeError("Please use SigningKey.generate() to construct me")
@classmethod
def generate(klass, curve=NIST192p, entropy=None, hashfunc=sha1):
secexp = randrange(curve.order, entropy)
return klass.from_secret_exponent(secexp, curve, hashfunc)
# to create a signing key from a short (arbitrary-length) seed, convert
# that seed into an integer with something like
# secexp=util.randrange_from_seed__X(seed, curve.order), and then pass
# that integer into SigningKey.from_secret_exponent(secexp, curve)
@classmethod
def from_secret_exponent(klass, secexp, curve=NIST192p, hashfunc=sha1):
self = klass(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = hashfunc
self.baselen = curve.baselen
n = curve.order
assert 1 <= secexp < n
pubkey_point = curve.generator*secexp
pubkey = ecdsa.Public_key(curve.generator, pubkey_point)
pubkey.order = n
self.verifying_key = VerifyingKey.from_public_point(pubkey_point, curve,
hashfunc)
self.privkey = ecdsa.Private_key(pubkey, secexp)
self.privkey.order = n
return self
@classmethod
def from_string(klass, string, curve=NIST192p, hashfunc=sha1):
assert len(string) == curve.baselen, (len(string), curve.baselen)
secexp = string_to_number(string)
return klass.from_secret_exponent(secexp, curve, hashfunc)
@classmethod
def from_pem(klass, string, hashfunc=sha1):
# the privkey pem file has two sections: "EC PARAMETERS" and "EC
# PRIVATE KEY". The first is redundant.
if PY3 and isinstance(string, str):
string = string.encode()
privkey_pem = string[string.index(b("-----BEGIN EC PRIVATE KEY-----")):]
return klass.from_der(der.unpem(privkey_pem), hashfunc)
@classmethod
def from_der(klass, string, hashfunc=sha1):
# SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1),
# cont[1],bitstring])
s, empty = der.remove_sequence(string)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER privkey: %s" %
binascii.hexlify(empty))
one, s = der.remove_integer(s)
if one != 1:
raise der.UnexpectedDER("expected '1' at start of DER privkey,"
" got %d" % one)
privkey_str, s = der.remove_octet_string(s)
tag, curve_oid_str, s = der.remove_constructed(s)
if tag != 0:
raise der.UnexpectedDER("expected tag 0 in DER privkey,"
" got %d" % tag)
curve_oid, empty = der.remove_object(curve_oid_str)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER privkey "
"curve_oid: %s" % binascii.hexlify(empty))
curve = find_curve(curve_oid)
# we don't actually care about the following fields
#
#tag, pubkey_bitstring, s = der.remove_constructed(s)
#if tag != 1:
# raise der.UnexpectedDER("expected tag 1 in DER privkey, got %d"
# % tag)
#pubkey_str = der.remove_bitstring(pubkey_bitstring)
#if empty != "":
# raise der.UnexpectedDER("trailing junk after DER privkey "
# "pubkeystr: %s" % binascii.hexlify(empty))
# our from_string method likes fixed-length privkey strings
if len(privkey_str) < curve.baselen:
privkey_str = b("\x00")*(curve.baselen-len(privkey_str)) + privkey_str
return klass.from_string(privkey_str, curve, hashfunc)
def to_string(self):
secexp = self.privkey.secret_multiplier
s = number_to_string(secexp, self.privkey.order)
return s
def to_pem(self):
# TODO: "BEGIN ECPARAMETERS"
return der.topem(self.to_der(), "EC PRIVATE KEY")
def to_der(self):
# SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1),
# cont[1],bitstring])
encoded_vk = b("\x00\x04") + self.get_verifying_key().to_string()
return der.encode_sequence(der.encode_integer(1),
der.encode_octet_string(self.to_string()),
der.encode_constructed(0, self.curve.encoded_oid),
der.encode_constructed(1, der.encode_bitstring(encoded_vk)),
)
def get_verifying_key(self):
return self.verifying_key
def sign_deterministic(self, data, hashfunc=None, sigencode=sigencode_string):
hashfunc = hashfunc or self.default_hashfunc
digest = hashfunc(data).digest()
return self.sign_digest_deterministic(digest, hashfunc=hashfunc, sigencode=sigencode)
def sign_digest_deterministic(self, digest, hashfunc=None, sigencode=sigencode_string):
"""
Calculates 'k' from data itself, removing the need for strong
random generator and producing deterministic (reproducible) signatures.
See RFC 6979 for more details.
"""
secexp = self.privkey.secret_multiplier
k = rfc6979.generate_k(
self.curve.generator.order(), secexp, hashfunc, digest)
return self.sign_digest(digest, sigencode=sigencode, k=k)
def sign(self, data, entropy=None, hashfunc=None, sigencode=sigencode_string, k=None):
"""
hashfunc= should behave like hashlib.sha1 . The output length of the
hash (in bytes) must not be longer than the length of the curve order
(rounded up to the nearest byte), so using SHA256 with nist256p is
ok, but SHA256 with nist192p is not. (In the 2**-96ish unlikely event
of a hash output larger than the curve order, the hash will
effectively be wrapped mod n).
Use hashfunc=hashlib.sha1 to match openssl's -ecdsa-with-SHA1 mode,
or hashfunc=hashlib.sha256 for openssl-1.0.0's -ecdsa-with-SHA256.
"""
hashfunc = hashfunc or self.default_hashfunc
h = hashfunc(data).digest()
return self.sign_digest(h, entropy, sigencode, k)
def sign_digest(self, digest, entropy=None, sigencode=sigencode_string, k=None):
if len(digest) > self.curve.baselen:
raise BadDigestError("this curve (%s) is too short "
"for your digest (%d)" % (self.curve.name,
8*len(digest)))
number = string_to_number(digest)
r, s = self.sign_number(number, entropy, k)
return sigencode(r, s, self.privkey.order)
def sign_number(self, number, entropy=None, k=None):
# returns a pair of numbers
order = self.privkey.order
# privkey.sign() may raise RuntimeError in the amazingly unlikely
# (2**-192) event that r=0 or s=0, because that would leak the key.
# We could re-try with a different 'k', but we couldn't test that
# code, so I choose to allow the signature to fail instead.
# If k is set, it is used directly. In other cases
# it is generated using entropy function
if k is not None:
_k = k
else:
_k = randrange(order, entropy)
assert 1 <= _k < order
sig = self.privkey.sign(number, _k)
return sig.r, sig.s

View File

@@ -0,0 +1,613 @@
#! /usr/bin/env python
#
# Provide some simple capabilities from number theory.
#
# Version of 2008.11.14.
#
# Written in 2005 and 2006 by Peter Pearson and placed in the public domain.
# Revision history:
# 2008.11.14: Use pow( base, exponent, modulus ) for modular_exp.
# Make gcd and lcm accept arbitrarly many arguments.
from __future__ import division
from .six import print_, integer_types
from .six.moves import reduce
import math
class Error( Exception ):
"""Base class for exceptions in this module."""
pass
class SquareRootError( Error ):
pass
class NegativeExponentError( Error ):
pass
def modular_exp( base, exponent, modulus ):
"Raise base to exponent, reducing by modulus"
if exponent < 0:
raise NegativeExponentError( "Negative exponents (%d) not allowed" \
% exponent )
return pow( base, exponent, modulus )
# result = 1L
# x = exponent
# b = base + 0L
# while x > 0:
# if x % 2 > 0: result = (result * b) % modulus
# x = x // 2
# b = ( b * b ) % modulus
# return result
def polynomial_reduce_mod( poly, polymod, p ):
"""Reduce poly by polymod, integer arithmetic modulo p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# This module has been tested only by extensive use
# in calculating modular square roots.
# Just to make this easy, require a monic polynomial:
assert polymod[-1] == 1
assert len( polymod ) > 1
while len( poly ) >= len( polymod ):
if poly[-1] != 0:
for i in range( 2, len( polymod ) + 1 ):
poly[-i] = ( poly[-i] - poly[-1] * polymod[-i] ) % p
poly = poly[0:-1]
return poly
def polynomial_multiply_mod( m1, m2, polymod, p ):
"""Polynomial multiplication modulo a polynomial over ints mod p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# This is just a seat-of-the-pants implementation.
# This module has been tested only by extensive use
# in calculating modular square roots.
# Initialize the product to zero:
prod = ( len( m1 ) + len( m2 ) - 1 ) * [0]
# Add together all the cross-terms:
for i in range( len( m1 ) ):
for j in range( len( m2 ) ):
prod[i+j] = ( prod[i+j] + m1[i] * m2[j] ) % p
return polynomial_reduce_mod( prod, polymod, p )
def polynomial_exp_mod( base, exponent, polymod, p ):
"""Polynomial exponentiation modulo a polynomial over ints mod p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# Based on the Handbook of Applied Cryptography, algorithm 2.227.
# This module has been tested only by extensive use
# in calculating modular square roots.
assert exponent < p
if exponent == 0: return [ 1 ]
G = base
k = exponent
if k%2 == 1: s = G
else: s = [ 1 ]
while k > 1:
k = k // 2
G = polynomial_multiply_mod( G, G, polymod, p )
if k%2 == 1: s = polynomial_multiply_mod( G, s, polymod, p )
return s
def jacobi( a, n ):
"""Jacobi symbol"""
# Based on the Handbook of Applied Cryptography (HAC), algorithm 2.149.
# This function has been tested by comparison with a small
# table printed in HAC, and by extensive use in calculating
# modular square roots.
assert n >= 3
assert n%2 == 1
a = a % n
if a == 0: return 0
if a == 1: return 1
a1, e = a, 0
while a1%2 == 0:
a1, e = a1//2, e+1
if e%2 == 0 or n%8 == 1 or n%8 == 7: s = 1
else: s = -1
if a1 == 1: return s
if n%4 == 3 and a1%4 == 3: s = -s
return s * jacobi( n % a1, a1 )
def square_root_mod_prime( a, p ):
"""Modular square root of a, mod p, p prime."""
# Based on the Handbook of Applied Cryptography, algorithms 3.34 to 3.39.
# This module has been tested for all values in [0,p-1] for
# every prime p from 3 to 1229.
assert 0 <= a < p
assert 1 < p
if a == 0: return 0
if p == 2: return a
jac = jacobi( a, p )
if jac == -1: raise SquareRootError( "%d has no square root modulo %d" \
% ( a, p ) )
if p % 4 == 3: return modular_exp( a, (p+1)//4, p )
if p % 8 == 5:
d = modular_exp( a, (p-1)//4, p )
if d == 1: return modular_exp( a, (p+3)//8, p )
if d == p-1: return ( 2 * a * modular_exp( 4*a, (p-5)//8, p ) ) % p
raise RuntimeError("Shouldn't get here.")
for b in range( 2, p ):
if jacobi( b*b-4*a, p ) == -1:
f = ( a, -b, 1 )
ff = polynomial_exp_mod( ( 0, 1 ), (p+1)//2, f, p )
assert ff[1] == 0
return ff[0]
raise RuntimeError("No b found.")
def inverse_mod( a, m ):
"""Inverse of a mod m."""
if a < 0 or m <= a: a = a % m
# From Ferguson and Schneier, roughly:
c, d = a, m
uc, vc, ud, vd = 1, 0, 0, 1
while c != 0:
q, c, d = divmod( d, c ) + ( c, )
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
# At this point, d is the GCD, and ud*a+vd*m = d.
# If d == 1, this means that ud is a inverse.
assert d == 1
if ud > 0: return ud
else: return ud + m
def gcd2(a, b):
"""Greatest common divisor using Euclid's algorithm."""
while a:
a, b = b%a, a
return b
def gcd( *a ):
"""Greatest common divisor.
Usage: gcd( [ 2, 4, 6 ] )
or: gcd( 2, 4, 6 )
"""
if len( a ) > 1: return reduce( gcd2, a )
if hasattr( a[0], "__iter__" ): return reduce( gcd2, a[0] )
return a[0]
def lcm2(a,b):
"""Least common multiple of two integers."""
return (a*b)//gcd(a,b)
def lcm( *a ):
"""Least common multiple.
Usage: lcm( [ 3, 4, 5 ] )
or: lcm( 3, 4, 5 )
"""
if len( a ) > 1: return reduce( lcm2, a )
if hasattr( a[0], "__iter__" ): return reduce( lcm2, a[0] )
return a[0]
def factorization( n ):
"""Decompose n into a list of (prime,exponent) pairs."""
assert isinstance( n, integer_types )
if n < 2: return []
result = []
d = 2
# Test the small primes:
for d in smallprimes:
if d > n: break
q, r = divmod( n, d )
if r == 0:
count = 1
while d <= n:
n = q
q, r = divmod( n, d )
if r != 0: break
count = count + 1
result.append( ( d, count ) )
# If n is still greater than the last of our small primes,
# it may require further work:
if n > smallprimes[-1]:
if is_prime( n ): # If what's left is prime, it's easy:
result.append( ( n, 1 ) )
else: # Ugh. Search stupidly for a divisor:
d = smallprimes[-1]
while 1:
d = d + 2 # Try the next divisor.
q, r = divmod( n, d )
if q < d: break # n < d*d means we're done, n = 1 or prime.
if r == 0: # d divides n. How many times?
count = 1
n = q
while d <= n: # As long as d might still divide n,
q, r = divmod( n, d ) # see if it does.
if r != 0: break
n = q # It does. Reduce n, increase count.
count = count + 1
result.append( ( d, count ) )
if n > 1: result.append( ( n, 1 ) )
return result
def phi( n ):
"""Return the Euler totient function of n."""
assert isinstance( n, integer_types )
if n < 3: return 1
result = 1
ff = factorization( n )
for f in ff:
e = f[1]
if e > 1:
result = result * f[0] ** (e-1) * ( f[0] - 1 )
else:
result = result * ( f[0] - 1 )
return result
def carmichael( n ):
"""Return Carmichael function of n.
Carmichael(n) is the smallest integer x such that
m**x = 1 mod n for all m relatively prime to n.
"""
return carmichael_of_factorized( factorization( n ) )
def carmichael_of_factorized( f_list ):
"""Return the Carmichael function of a number that is
represented as a list of (prime,exponent) pairs.
"""
if len( f_list ) < 1: return 1
result = carmichael_of_ppower( f_list[0] )
for i in range( 1, len( f_list ) ):
result = lcm( result, carmichael_of_ppower( f_list[i] ) )
return result
def carmichael_of_ppower( pp ):
"""Carmichael function of the given power of the given prime.
"""
p, a = pp
if p == 2 and a > 2: return 2**(a-2)
else: return (p-1) * p**(a-1)
def order_mod( x, m ):
"""Return the order of x in the multiplicative group mod m.
"""
# Warning: this implementation is not very clever, and will
# take a long time if m is very large.
if m <= 1: return 0
assert gcd( x, m ) == 1
z = x
result = 1
while z != 1:
z = ( z * x ) % m
result = result + 1
return result
def largest_factor_relatively_prime( a, b ):
"""Return the largest factor of a relatively prime to b.
"""
while 1:
d = gcd( a, b )
if d <= 1: break
b = d
while 1:
q, r = divmod( a, d )
if r > 0:
break
a = q
return a
def kinda_order_mod( x, m ):
"""Return the order of x in the multiplicative group mod m',
where m' is the largest factor of m relatively prime to x.
"""
return order_mod( x, largest_factor_relatively_prime( m, x ) )
def is_prime( n ):
"""Return True if x is prime, False otherwise.
We use the Miller-Rabin test, as given in Menezes et al. p. 138.
This test is not exact: there are composite values n for which
it returns True.
In testing the odd numbers from 10000001 to 19999999,
about 66 composites got past the first test,
5 got past the second test, and none got past the third.
Since factors of 2, 3, 5, 7, and 11 were detected during
preliminary screening, the number of numbers tested by
Miller-Rabin was (19999999 - 10000001)*(2/3)*(4/5)*(6/7)
= 4.57 million.
"""
# (This is used to study the risk of false positives:)
global miller_rabin_test_count
miller_rabin_test_count = 0
if n <= smallprimes[-1]:
if n in smallprimes: return True
else: return False
if gcd( n, 2*3*5*7*11 ) != 1: return False
# Choose a number of iterations sufficient to reduce the
# probability of accepting a composite below 2**-80
# (from Menezes et al. Table 4.4):
t = 40
n_bits = 1 + int( math.log( n, 2 ) )
for k, tt in ( ( 100, 27 ),
( 150, 18 ),
( 200, 15 ),
( 250, 12 ),
( 300, 9 ),
( 350, 8 ),
( 400, 7 ),
( 450, 6 ),
( 550, 5 ),
( 650, 4 ),
( 850, 3 ),
( 1300, 2 ),
):
if n_bits < k: break
t = tt
# Run the test t times:
s = 0
r = n - 1
while ( r % 2 ) == 0:
s = s + 1
r = r // 2
for i in range( t ):
a = smallprimes[ i ]
y = modular_exp( a, r, n )
if y != 1 and y != n-1:
j = 1
while j <= s - 1 and y != n - 1:
y = modular_exp( y, 2, n )
if y == 1:
miller_rabin_test_count = i + 1
return False
j = j + 1
if y != n-1:
miller_rabin_test_count = i + 1
return False
return True
def next_prime( starting_value ):
"Return the smallest prime larger than the starting value."
if starting_value < 2: return 2
result = ( starting_value + 1 ) | 1
while not is_prime( result ): result = result + 2
return result
smallprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
383, 389, 397, 401, 409, 419, 421, 431, 433, 439,
443, 449, 457, 461, 463, 467, 479, 487, 491, 499,
503, 509, 521, 523, 541, 547, 557, 563, 569, 571,
577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
641, 643, 647, 653, 659, 661, 673, 677, 683, 691,
701, 709, 719, 727, 733, 739, 743, 751, 757, 761,
769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
839, 853, 857, 859, 863, 877, 881, 883, 887, 907,
911, 919, 929, 937, 941, 947, 953, 967, 971, 977,
983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093,
1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229]
miller_rabin_test_count = 0
def __main__():
# Making sure locally defined exceptions work:
# p = modular_exp( 2, -2, 3 )
# p = square_root_mod_prime( 2, 3 )
print_("Testing gcd...")
assert gcd( 3*5*7, 3*5*11, 3*5*13 ) == 3*5
assert gcd( [ 3*5*7, 3*5*11, 3*5*13 ] ) == 3*5
assert gcd( 3 ) == 3
print_("Testing lcm...")
assert lcm( 3, 5*3, 7*3 ) == 3*5*7
assert lcm( [ 3, 5*3, 7*3 ] ) == 3*5*7
assert lcm( 3 ) == 3
print_("Testing next_prime...")
bigprimes = ( 999671,
999683,
999721,
999727,
999749,
999763,
999769,
999773,
999809,
999853,
999863,
999883,
999907,
999917,
999931,
999953,
999959,
999961,
999979,
999983 )
for i in range( len( bigprimes ) - 1 ):
assert next_prime( bigprimes[i] ) == bigprimes[ i+1 ]
error_tally = 0
# Test the square_root_mod_prime function:
for p in smallprimes:
print_("Testing square_root_mod_prime for modulus p = %d." % p)
squares = []
for root in range( 0, 1+p//2 ):
sq = ( root * root ) % p
squares.append( sq )
calculated = square_root_mod_prime( sq, p )
if ( calculated * calculated ) % p != sq:
error_tally = error_tally + 1
print_("Failed to find %d as sqrt( %d ) mod %d. Said %d." % \
( root, sq, p, calculated ))
for nonsquare in range( 0, p ):
if nonsquare not in squares:
try:
calculated = square_root_mod_prime( nonsquare, p )
except SquareRootError:
pass
else:
error_tally = error_tally + 1
print_("Failed to report no root for sqrt( %d ) mod %d." % \
( nonsquare, p ))
# Test the jacobi function:
for m in range( 3, 400, 2 ):
print_("Testing jacobi for modulus m = %d." % m)
if is_prime( m ):
squares = []
for root in range( 1, m ):
if jacobi( root * root, m ) != 1:
error_tally = error_tally + 1
print_("jacobi( %d * %d, %d ) != 1" % ( root, root, m ))
squares.append( root * root % m )
for i in range( 1, m ):
if not i in squares:
if jacobi( i, m ) != -1:
error_tally = error_tally + 1
print_("jacobi( %d, %d ) != -1" % ( i, m ))
else: # m is not prime.
f = factorization( m )
for a in range( 1, m ):
c = 1
for i in f:
c = c * jacobi( a, i[0] ) ** i[1]
if c != jacobi( a, m ):
error_tally = error_tally + 1
print_("%d != jacobi( %d, %d )" % ( c, a, m ))
# Test the inverse_mod function:
print_("Testing inverse_mod . . .")
import random
n_tests = 0
for i in range( 100 ):
m = random.randint( 20, 10000 )
for j in range( 100 ):
a = random.randint( 1, m-1 )
if gcd( a, m ) == 1:
n_tests = n_tests + 1
inv = inverse_mod( a, m )
if inv <= 0 or inv >= m or ( a * inv ) % m != 1:
error_tally = error_tally + 1
print_("%d = inverse_mod( %d, %d ) is wrong." % ( inv, a, m ))
assert n_tests > 1000
print_(n_tests, " tests of inverse_mod completed.")
class FailedTest(Exception): pass
print_(error_tally, "errors detected.")
if error_tally != 0:
raise FailedTest("%d errors detected" % error_tally)
if __name__ == '__main__':
__main__()

103
bin/python/ecdsa/rfc6979.py Normal file
View File

@@ -0,0 +1,103 @@
'''
RFC 6979:
Deterministic Usage of the Digital Signature Algorithm (DSA) and
Elliptic Curve Digital Signature Algorithm (ECDSA)
http://tools.ietf.org/html/rfc6979
Many thanks to Coda Hale for his implementation in Go language:
https://github.com/codahale/rfc6979
'''
import hmac
from binascii import hexlify
from .util import number_to_string, number_to_string_crop
from .six import b
try:
bin(0)
except NameError:
binmap = {"0": "0000", "1": "0001", "2": "0010", "3": "0011",
"4": "0100", "5": "0101", "6": "0110", "7": "0111",
"8": "1000", "9": "1001", "a": "1010", "b": "1011",
"c": "1100", "d": "1101", "e": "1110", "f": "1111"}
def bin(value): # for python2.5
v = "".join(binmap[x] for x in "%x"%abs(value)).lstrip("0")
if value < 0:
return "-0b" + v
return "0b" + v
def bit_length(num):
# http://docs.python.org/dev/library/stdtypes.html#int.bit_length
s = bin(num) # binary representation: bin(-37) --> '-0b100101'
s = s.lstrip('-0b') # remove leading zeros and minus sign
return len(s) # len('100101') --> 6
def bits2int(data, qlen):
x = int(hexlify(data), 16)
l = len(data) * 8
if l > qlen:
return x >> (l-qlen)
return x
def bits2octets(data, order):
z1 = bits2int(data, bit_length(order))
z2 = z1 - order
if z2 < 0:
z2 = z1
return number_to_string_crop(z2, order)
# https://tools.ietf.org/html/rfc6979#section-3.2
def generate_k(order, secexp, hash_func, data):
'''
generator - order of the DSA generator used in the signature
secexp - secure exponent (private key) in numeric form
hash_func - reference to the same hash function used for generating hash
data - hash in binary form of the signing data
'''
qlen = bit_length(order)
holen = hash_func().digest_size
rolen = (qlen + 7) / 8
bx = number_to_string(secexp, order) + bits2octets(data, order)
# Step B
v = b('\x01') * holen
# Step C
k = b('\x00') * holen
# Step D
k = hmac.new(k, v+b('\x00')+bx, hash_func).digest()
# Step E
v = hmac.new(k, v, hash_func).digest()
# Step F
k = hmac.new(k, v+b('\x01')+bx, hash_func).digest()
# Step G
v = hmac.new(k, v, hash_func).digest()
# Step H
while True:
# Step H1
t = b('')
# Step H2
while len(t) < rolen:
v = hmac.new(k, v, hash_func).digest()
t += v
# Step H3
secret = bits2int(t, qlen)
if secret >= 1 and secret < order:
return secret
k = hmac.new(k, v+b('\x00'), hash_func).digest()
v = hmac.new(k, v, hash_func).digest()

394
bin/python/ecdsa/six.py Normal file
View File

@@ -0,0 +1,394 @@
"""Utilities for writing code that runs on Python 2 and 3"""
# Copyright (c) 2010-2012 Benjamin Peterson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import operator
import sys
import types
__author__ = "Benjamin Peterson <benjamin@python.org>"
__version__ = "1.2.0"
# True if we are running on Python 3.
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes
MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
class_types = (type, types.ClassType)
text_type = unicode
binary_type = str
if sys.platform.startswith("java"):
# Jython always uses 32 bits.
MAXSIZE = int((1 << 31) - 1)
else:
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
class X(object):
def __len__(self):
return 1 << 31
try:
len(X())
except OverflowError:
# 32-bit
MAXSIZE = int((1 << 31) - 1)
else:
# 64-bit
MAXSIZE = int((1 << 63) - 1)
del X
def _add_doc(func, doc):
"""Add documentation to a function."""
func.__doc__ = doc
def _import_module(name):
"""Import module, returning the module after the last dot."""
__import__(name)
return sys.modules[name]
class _LazyDescr(object):
def __init__(self, name):
self.name = name
def __get__(self, obj, tp):
result = self._resolve()
setattr(obj, self.name, result)
# This is a bit ugly, but it avoids running this again.
delattr(tp, self.name)
return result
class MovedModule(_LazyDescr):
def __init__(self, name, old, new=None):
super(MovedModule, self).__init__(name)
if PY3:
if new is None:
new = name
self.mod = new
else:
self.mod = old
def _resolve(self):
return _import_module(self.mod)
class MovedAttribute(_LazyDescr):
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
super(MovedAttribute, self).__init__(name)
if PY3:
if new_mod is None:
new_mod = name
self.mod = new_mod
if new_attr is None:
if old_attr is None:
new_attr = name
else:
new_attr = old_attr
self.attr = new_attr
else:
self.mod = old_mod
if old_attr is None:
old_attr = name
self.attr = old_attr
def _resolve(self):
module = _import_module(self.mod)
return getattr(module, self.attr)
class _MovedItems(types.ModuleType):
"""Lazy loading of moved objects"""
_moved_attributes = [
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
MovedAttribute("reduce", "__builtin__", "functools"),
MovedAttribute("StringIO", "StringIO", "io"),
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
MovedModule("builtins", "__builtin__"),
MovedModule("configparser", "ConfigParser"),
MovedModule("copyreg", "copy_reg"),
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
MovedModule("http_cookies", "Cookie", "http.cookies"),
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
MovedModule("html_parser", "HTMLParser", "html.parser"),
MovedModule("http_client", "httplib", "http.client"),
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
MovedModule("cPickle", "cPickle", "pickle"),
MovedModule("queue", "Queue"),
MovedModule("reprlib", "repr"),
MovedModule("socketserver", "SocketServer"),
MovedModule("tkinter", "Tkinter"),
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
MovedModule("tkinter_colorchooser", "tkColorChooser",
"tkinter.colorchooser"),
MovedModule("tkinter_commondialog", "tkCommonDialog",
"tkinter.commondialog"),
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
"tkinter.simpledialog"),
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
MovedModule("winreg", "_winreg"),
]
for attr in _moved_attributes:
setattr(_MovedItems, attr.name, attr)
del attr
moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves")
def add_move(move):
"""Add an item to six.moves."""
setattr(_MovedItems, move.name, move)
def remove_move(name):
"""Remove item from six.moves."""
try:
delattr(_MovedItems, name)
except AttributeError:
try:
del moves.__dict__[name]
except KeyError:
raise AttributeError("no such move, %r" % (name,))
if PY3:
_meth_func = "__func__"
_meth_self = "__self__"
_func_code = "__code__"
_func_defaults = "__defaults__"
_iterkeys = "keys"
_itervalues = "values"
_iteritems = "items"
else:
_meth_func = "im_func"
_meth_self = "im_self"
_func_code = "func_code"
_func_defaults = "func_defaults"
_iterkeys = "iterkeys"
_itervalues = "itervalues"
_iteritems = "iteritems"
try:
advance_iterator = next
except NameError:
def advance_iterator(it):
return it.next()
next = advance_iterator
try:
callable = callable
except NameError:
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
if PY3:
def get_unbound_function(unbound):
return unbound
Iterator = object
else:
def get_unbound_function(unbound):
return unbound.im_func
class Iterator(object):
def next(self):
return type(self).__next__(self)
callable = callable
_add_doc(get_unbound_function,
"""Get the function out of a possibly unbound function""")
get_method_function = operator.attrgetter(_meth_func)
get_method_self = operator.attrgetter(_meth_self)
get_function_code = operator.attrgetter(_func_code)
get_function_defaults = operator.attrgetter(_func_defaults)
def iterkeys(d):
"""Return an iterator over the keys of a dictionary."""
return iter(getattr(d, _iterkeys)())
def itervalues(d):
"""Return an iterator over the values of a dictionary."""
return iter(getattr(d, _itervalues)())
def iteritems(d):
"""Return an iterator over the (key, value) pairs of a dictionary."""
return iter(getattr(d, _iteritems)())
if PY3:
def b(s):
return s.encode("latin-1")
def u(s):
return s
if sys.version_info[1] <= 1:
def int2byte(i):
return bytes((i,))
else:
# This is about 2x faster than the implementation above on 3.2+
int2byte = operator.methodcaller("to_bytes", 1, "big")
import io
StringIO = io.StringIO
BytesIO = io.BytesIO
else:
def b(s):
return s
def u(s):
if isinstance(s, unicode):
return s
return unicode(s, "unicode_escape")
int2byte = chr
import StringIO
StringIO = BytesIO = StringIO.StringIO
_add_doc(b, """Byte literal""")
_add_doc(u, """Text literal""")
if PY3:
import builtins
exec_ = getattr(builtins, "exec")
def reraise(tp, value, tb=None):
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
print_ = getattr(builtins, "print")
del builtins
else:
def exec_(_code_, _globs_=None, _locs_=None):
"""Execute code in a namespace."""
if _globs_ is None:
frame = sys._getframe(1)
_globs_ = frame.f_globals
if _locs_ is None:
_locs_ = frame.f_locals
del frame
elif _locs_ is None:
_locs_ = _globs_
exec("""exec _code_ in _globs_, _locs_""")
exec_("""def reraise(tp, value, tb=None):
raise tp, value, tb
""")
def print_(*args, **kwargs):
"""The new-style print function."""
fp = kwargs.pop("file", sys.stdout)
if fp is None:
return
def write(data):
if not isinstance(data, basestring):
data = str(data)
fp.write(data)
want_unicode = False
sep = kwargs.pop("sep", None)
if sep is not None:
if isinstance(sep, unicode):
want_unicode = True
elif not isinstance(sep, str):
raise TypeError("sep must be None or a string")
end = kwargs.pop("end", None)
if end is not None:
if isinstance(end, unicode):
want_unicode = True
elif not isinstance(end, str):
raise TypeError("end must be None or a string")
if kwargs:
raise TypeError("invalid keyword arguments to print()")
if not want_unicode:
for arg in args:
if isinstance(arg, unicode):
want_unicode = True
break
if want_unicode:
newline = unicode("\n")
space = unicode(" ")
else:
newline = "\n"
space = " "
if sep is None:
sep = space
if end is None:
end = newline
for i, arg in enumerate(args):
if i:
write(sep)
write(arg)
write(end)
_add_doc(reraise, """Reraise an exception.""")
def with_metaclass(meta, base=object):
"""Create a base class with a metaclass."""
return meta("NewBase", (base,), {})

View File

@@ -0,0 +1,663 @@
from __future__ import with_statement, division
import unittest
import os
import time
import shutil
import subprocess
from binascii import hexlify, unhexlify
from hashlib import sha1, sha256, sha512
from .six import b, print_, binary_type
from .keys import SigningKey, VerifyingKey
from .keys import BadSignatureError
from . import util
from .util import sigencode_der, sigencode_strings
from .util import sigdecode_der, sigdecode_strings
from .curves import Curve, UnknownCurveError
from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1
from .ellipticcurve import Point
from . import der
from . import rfc6979
class SubprocessError(Exception):
pass
def run_openssl(cmd):
OPENSSL = "openssl"
p = subprocess.Popen([OPENSSL] + cmd.split(),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout, ignored = p.communicate()
if p.returncode != 0:
raise SubprocessError("cmd '%s %s' failed: rc=%s, stdout/err was %s" %
(OPENSSL, cmd, p.returncode, stdout))
return stdout.decode()
BENCH = False
class ECDSA(unittest.TestCase):
def test_basic(self):
priv = SigningKey.generate()
pub = priv.get_verifying_key()
data = b("blahblah")
sig = priv.sign(data)
self.assertTrue(pub.verify(sig, data))
self.assertRaises(BadSignatureError, pub.verify, sig, data+b("bad"))
pub2 = VerifyingKey.from_string(pub.to_string())
self.assertTrue(pub2.verify(sig, data))
def test_deterministic(self):
data = b("blahblah")
secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16)
priv = SigningKey.from_secret_exponent(secexp, SECP256k1, sha256)
pub = priv.get_verifying_key()
k = rfc6979.generate_k(
SECP256k1.generator.order(), secexp, sha256, sha256(data).digest())
sig1 = priv.sign(data, k=k)
self.assertTrue(pub.verify(sig1, data))
sig2 = priv.sign(data, k=k)
self.assertTrue(pub.verify(sig2, data))
sig3 = priv.sign_deterministic(data, sha256)
self.assertTrue(pub.verify(sig3, data))
self.assertEqual(sig1, sig2)
self.assertEqual(sig1, sig3)
def test_bad_usage(self):
# sk=SigningKey() is wrong
self.assertRaises(TypeError, SigningKey)
self.assertRaises(TypeError, VerifyingKey)
def test_lengths(self):
default = NIST192p
priv = SigningKey.generate()
pub = priv.get_verifying_key()
self.assertEqual(len(pub.to_string()), default.verifying_key_length)
sig = priv.sign(b("data"))
self.assertEqual(len(sig), default.signature_length)
if BENCH:
print_()
for curve in (NIST192p, NIST224p, NIST256p, NIST384p, NIST521p):
start = time.time()
priv = SigningKey.generate(curve=curve)
pub1 = priv.get_verifying_key()
keygen_time = time.time() - start
pub2 = VerifyingKey.from_string(pub1.to_string(), curve)
self.assertEqual(pub1.to_string(), pub2.to_string())
self.assertEqual(len(pub1.to_string()),
curve.verifying_key_length)
start = time.time()
sig = priv.sign(b("data"))
sign_time = time.time() - start
self.assertEqual(len(sig), curve.signature_length)
if BENCH:
start = time.time()
pub1.verify(sig, b("data"))
verify_time = time.time() - start
print_("%s: siglen=%d, keygen=%0.3fs, sign=%0.3f, verify=%0.3f" \
% (curve.name, curve.signature_length,
keygen_time, sign_time, verify_time))
def test_serialize(self):
seed = b("secret")
curve = NIST192p
secexp1 = util.randrange_from_seed__trytryagain(seed, curve.order)
secexp2 = util.randrange_from_seed__trytryagain(seed, curve.order)
self.assertEqual(secexp1, secexp2)
priv1 = SigningKey.from_secret_exponent(secexp1, curve)
priv2 = SigningKey.from_secret_exponent(secexp2, curve)
self.assertEqual(hexlify(priv1.to_string()),
hexlify(priv2.to_string()))
self.assertEqual(priv1.to_pem(), priv2.to_pem())
pub1 = priv1.get_verifying_key()
pub2 = priv2.get_verifying_key()
data = b("data")
sig1 = priv1.sign(data)
sig2 = priv2.sign(data)
self.assertTrue(pub1.verify(sig1, data))
self.assertTrue(pub2.verify(sig1, data))
self.assertTrue(pub1.verify(sig2, data))
self.assertTrue(pub2.verify(sig2, data))
self.assertEqual(hexlify(pub1.to_string()),
hexlify(pub2.to_string()))
def test_nonrandom(self):
s = b("all the entropy in the entire world, compressed into one line")
def not_much_entropy(numbytes):
return s[:numbytes]
# we control the entropy source, these two keys should be identical:
priv1 = SigningKey.generate(entropy=not_much_entropy)
priv2 = SigningKey.generate(entropy=not_much_entropy)
self.assertEqual(hexlify(priv1.get_verifying_key().to_string()),
hexlify(priv2.get_verifying_key().to_string()))
# likewise, signatures should be identical. Obviously you'd never
# want to do this with keys you care about, because the secrecy of
# the private key depends upon using different random numbers for
# each signature
sig1 = priv1.sign(b("data"), entropy=not_much_entropy)
sig2 = priv2.sign(b("data"), entropy=not_much_entropy)
self.assertEqual(hexlify(sig1), hexlify(sig2))
def assertTruePrivkeysEqual(self, priv1, priv2):
self.assertEqual(priv1.privkey.secret_multiplier,
priv2.privkey.secret_multiplier)
self.assertEqual(priv1.privkey.public_key.generator,
priv2.privkey.public_key.generator)
def failIfPrivkeysEqual(self, priv1, priv2):
self.failIfEqual(priv1.privkey.secret_multiplier,
priv2.privkey.secret_multiplier)
def test_privkey_creation(self):
s = b("all the entropy in the entire world, compressed into one line")
def not_much_entropy(numbytes):
return s[:numbytes]
priv1 = SigningKey.generate()
self.assertEqual(priv1.baselen, NIST192p.baselen)
priv1 = SigningKey.generate(curve=NIST224p)
self.assertEqual(priv1.baselen, NIST224p.baselen)
priv1 = SigningKey.generate(entropy=not_much_entropy)
self.assertEqual(priv1.baselen, NIST192p.baselen)
priv2 = SigningKey.generate(entropy=not_much_entropy)
self.assertEqual(priv2.baselen, NIST192p.baselen)
self.assertTruePrivkeysEqual(priv1, priv2)
priv1 = SigningKey.from_secret_exponent(secexp=3)
self.assertEqual(priv1.baselen, NIST192p.baselen)
priv2 = SigningKey.from_secret_exponent(secexp=3)
self.assertTruePrivkeysEqual(priv1, priv2)
priv1 = SigningKey.from_secret_exponent(secexp=4, curve=NIST224p)
self.assertEqual(priv1.baselen, NIST224p.baselen)
def test_privkey_strings(self):
priv1 = SigningKey.generate()
s1 = priv1.to_string()
self.assertEqual(type(s1), binary_type)
self.assertEqual(len(s1), NIST192p.baselen)
priv2 = SigningKey.from_string(s1)
self.assertTruePrivkeysEqual(priv1, priv2)
s1 = priv1.to_pem()
self.assertEqual(type(s1), binary_type)
self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----")))
self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----")))
priv2 = SigningKey.from_pem(s1)
self.assertTruePrivkeysEqual(priv1, priv2)
s1 = priv1.to_der()
self.assertEqual(type(s1), binary_type)
priv2 = SigningKey.from_der(s1)
self.assertTruePrivkeysEqual(priv1, priv2)
priv1 = SigningKey.generate(curve=NIST256p)
s1 = priv1.to_pem()
self.assertEqual(type(s1), binary_type)
self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----")))
self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----")))
priv2 = SigningKey.from_pem(s1)
self.assertTruePrivkeysEqual(priv1, priv2)
s1 = priv1.to_der()
self.assertEqual(type(s1), binary_type)
priv2 = SigningKey.from_der(s1)
self.assertTruePrivkeysEqual(priv1, priv2)
def assertTruePubkeysEqual(self, pub1, pub2):
self.assertEqual(pub1.pubkey.point, pub2.pubkey.point)
self.assertEqual(pub1.pubkey.generator, pub2.pubkey.generator)
self.assertEqual(pub1.curve, pub2.curve)
def test_pubkey_strings(self):
priv1 = SigningKey.generate()
pub1 = priv1.get_verifying_key()
s1 = pub1.to_string()
self.assertEqual(type(s1), binary_type)
self.assertEqual(len(s1), NIST192p.verifying_key_length)
pub2 = VerifyingKey.from_string(s1)
self.assertTruePubkeysEqual(pub1, pub2)
priv1 = SigningKey.generate(curve=NIST256p)
pub1 = priv1.get_verifying_key()
s1 = pub1.to_string()
self.assertEqual(type(s1), binary_type)
self.assertEqual(len(s1), NIST256p.verifying_key_length)
pub2 = VerifyingKey.from_string(s1, curve=NIST256p)
self.assertTruePubkeysEqual(pub1, pub2)
pub1_der = pub1.to_der()
self.assertEqual(type(pub1_der), binary_type)
pub2 = VerifyingKey.from_der(pub1_der)
self.assertTruePubkeysEqual(pub1, pub2)
self.assertRaises(der.UnexpectedDER,
VerifyingKey.from_der, pub1_der+b("junk"))
badpub = VerifyingKey.from_der(pub1_der)
class FakeGenerator:
def order(self): return 123456789
badcurve = Curve("unknown", None, None, FakeGenerator(), (1,2,3,4,5,6))
badpub.curve = badcurve
badder = badpub.to_der()
self.assertRaises(UnknownCurveError, VerifyingKey.from_der, badder)
pem = pub1.to_pem()
self.assertEqual(type(pem), binary_type)
self.assertTrue(pem.startswith(b("-----BEGIN PUBLIC KEY-----")), pem)
self.assertTrue(pem.strip().endswith(b("-----END PUBLIC KEY-----")), pem)
pub2 = VerifyingKey.from_pem(pem)
self.assertTruePubkeysEqual(pub1, pub2)
def test_signature_strings(self):
priv1 = SigningKey.generate()
pub1 = priv1.get_verifying_key()
data = b("data")
sig = priv1.sign(data)
self.assertEqual(type(sig), binary_type)
self.assertEqual(len(sig), NIST192p.signature_length)
self.assertTrue(pub1.verify(sig, data))
sig = priv1.sign(data, sigencode=sigencode_strings)
self.assertEqual(type(sig), tuple)
self.assertEqual(len(sig), 2)
self.assertEqual(type(sig[0]), binary_type)
self.assertEqual(type(sig[1]), binary_type)
self.assertEqual(len(sig[0]), NIST192p.baselen)
self.assertEqual(len(sig[1]), NIST192p.baselen)
self.assertTrue(pub1.verify(sig, data, sigdecode=sigdecode_strings))
sig_der = priv1.sign(data, sigencode=sigencode_der)
self.assertEqual(type(sig_der), binary_type)
self.assertTrue(pub1.verify(sig_der, data, sigdecode=sigdecode_der))
def test_hashfunc(self):
sk = SigningKey.generate(curve=NIST256p, hashfunc=sha256)
data = b("security level is 128 bits")
sig = sk.sign(data)
vk = VerifyingKey.from_string(sk.get_verifying_key().to_string(),
curve=NIST256p, hashfunc=sha256)
self.assertTrue(vk.verify(sig, data))
sk2 = SigningKey.generate(curve=NIST256p)
sig2 = sk2.sign(data, hashfunc=sha256)
vk2 = VerifyingKey.from_string(sk2.get_verifying_key().to_string(),
curve=NIST256p, hashfunc=sha256)
self.assertTrue(vk2.verify(sig2, data))
vk3 = VerifyingKey.from_string(sk.get_verifying_key().to_string(),
curve=NIST256p)
self.assertTrue(vk3.verify(sig, data, hashfunc=sha256))
class OpenSSL(unittest.TestCase):
# test interoperability with OpenSSL tools. Note that openssl's ECDSA
# sign/verify arguments changed between 0.9.8 and 1.0.0: the early
# versions require "-ecdsa-with-SHA1", the later versions want just
# "-SHA1" (or to leave out that argument entirely, which means the
# signature will use some default digest algorithm, probably determined
# by the key, probably always SHA1).
#
# openssl ecparam -name secp224r1 -genkey -out privkey.pem
# openssl ec -in privkey.pem -text -noout # get the priv/pub keys
# openssl dgst -ecdsa-with-SHA1 -sign privkey.pem -out data.sig data.txt
# openssl asn1parse -in data.sig -inform DER
# data.sig is 64 bytes, probably 56b plus ASN1 overhead
# openssl dgst -ecdsa-with-SHA1 -prverify privkey.pem -signature data.sig data.txt ; echo $?
# openssl ec -in privkey.pem -pubout -out pubkey.pem
# openssl ec -in privkey.pem -pubout -outform DER -out pubkey.der
def get_openssl_messagedigest_arg(self):
v = run_openssl("version")
# e.g. "OpenSSL 1.0.0 29 Mar 2010", or "OpenSSL 1.0.0a 1 Jun 2010",
# or "OpenSSL 0.9.8o 01 Jun 2010"
vs = v.split()[1].split(".")
if vs >= ["1","0","0"]:
return "-SHA1"
else:
return "-ecdsa-with-SHA1"
# sk: 1:OpenSSL->python 2:python->OpenSSL
# vk: 3:OpenSSL->python 4:python->OpenSSL
# sig: 5:OpenSSL->python 6:python->OpenSSL
def test_from_openssl_nist192p(self):
return self.do_test_from_openssl(NIST192p)
def test_from_openssl_nist224p(self):
return self.do_test_from_openssl(NIST224p)
def test_from_openssl_nist256p(self):
return self.do_test_from_openssl(NIST256p)
def test_from_openssl_nist384p(self):
return self.do_test_from_openssl(NIST384p)
def test_from_openssl_nist521p(self):
return self.do_test_from_openssl(NIST521p)
def test_from_openssl_secp256k1(self):
return self.do_test_from_openssl(SECP256k1)
def do_test_from_openssl(self, curve):
curvename = curve.openssl_name
assert curvename
# OpenSSL: create sk, vk, sign.
# Python: read vk(3), checksig(5), read sk(1), sign, check
mdarg = self.get_openssl_messagedigest_arg()
if os.path.isdir("t"):
shutil.rmtree("t")
os.mkdir("t")
run_openssl("ecparam -name %s -genkey -out t/privkey.pem" % curvename)
run_openssl("ec -in t/privkey.pem -pubout -out t/pubkey.pem")
data = b("data")
with open("t/data.txt","wb") as e: e.write(data)
run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig t/data.txt" % mdarg)
run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig t/data.txt" % mdarg)
with open("t/pubkey.pem","rb") as e: pubkey_pem = e.read()
vk = VerifyingKey.from_pem(pubkey_pem) # 3
with open("t/data.sig","rb") as e: sig_der = e.read()
self.assertTrue(vk.verify(sig_der, data, # 5
hashfunc=sha1, sigdecode=sigdecode_der))
with open("t/privkey.pem") as e: fp = e.read()
sk = SigningKey.from_pem(fp) # 1
sig = sk.sign(data)
self.assertTrue(vk.verify(sig, data))
def test_to_openssl_nist192p(self):
self.do_test_to_openssl(NIST192p)
def test_to_openssl_nist224p(self):
self.do_test_to_openssl(NIST224p)
def test_to_openssl_nist256p(self):
self.do_test_to_openssl(NIST256p)
def test_to_openssl_nist384p(self):
self.do_test_to_openssl(NIST384p)
def test_to_openssl_nist521p(self):
self.do_test_to_openssl(NIST521p)
def test_to_openssl_secp256k1(self):
self.do_test_to_openssl(SECP256k1)
def do_test_to_openssl(self, curve):
curvename = curve.openssl_name
assert curvename
# Python: create sk, vk, sign.
# OpenSSL: read vk(4), checksig(6), read sk(2), sign, check
mdarg = self.get_openssl_messagedigest_arg()
if os.path.isdir("t"):
shutil.rmtree("t")
os.mkdir("t")
sk = SigningKey.generate(curve=curve)
vk = sk.get_verifying_key()
data = b("data")
with open("t/pubkey.der","wb") as e: e.write(vk.to_der()) # 4
with open("t/pubkey.pem","wb") as e: e.write(vk.to_pem()) # 4
sig_der = sk.sign(data, hashfunc=sha1, sigencode=sigencode_der)
with open("t/data.sig","wb") as e: e.write(sig_der) # 6
with open("t/data.txt","wb") as e: e.write(data)
with open("t/baddata.txt","wb") as e: e.write(data+b("corrupt"))
self.assertRaises(SubprocessError, run_openssl,
"dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/baddata.txt" % mdarg)
run_openssl("dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/data.txt" % mdarg)
with open("t/privkey.pem","wb") as e: e.write(sk.to_pem()) # 2
run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig2 t/data.txt" % mdarg)
run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig2 t/data.txt" % mdarg)
class DER(unittest.TestCase):
def test_oids(self):
oid_ecPublicKey = der.encode_oid(1, 2, 840, 10045, 2, 1)
self.assertEqual(hexlify(oid_ecPublicKey), b("06072a8648ce3d0201"))
self.assertEqual(hexlify(NIST224p.encoded_oid), b("06052b81040021"))
self.assertEqual(hexlify(NIST256p.encoded_oid),
b("06082a8648ce3d030107"))
x = oid_ecPublicKey + b("more")
x1, rest = der.remove_object(x)
self.assertEqual(x1, (1, 2, 840, 10045, 2, 1))
self.assertEqual(rest, b("more"))
def test_integer(self):
self.assertEqual(der.encode_integer(0), b("\x02\x01\x00"))
self.assertEqual(der.encode_integer(1), b("\x02\x01\x01"))
self.assertEqual(der.encode_integer(127), b("\x02\x01\x7f"))
self.assertEqual(der.encode_integer(128), b("\x02\x02\x00\x80"))
self.assertEqual(der.encode_integer(256), b("\x02\x02\x01\x00"))
#self.assertEqual(der.encode_integer(-1), b("\x02\x01\xff"))
def s(n): return der.remove_integer(der.encode_integer(n) + b("junk"))
self.assertEqual(s(0), (0, b("junk")))
self.assertEqual(s(1), (1, b("junk")))
self.assertEqual(s(127), (127, b("junk")))
self.assertEqual(s(128), (128, b("junk")))
self.assertEqual(s(256), (256, b("junk")))
self.assertEqual(s(1234567890123456789012345678901234567890),
(1234567890123456789012345678901234567890,b("junk")))
def test_number(self):
self.assertEqual(der.encode_number(0), b("\x00"))
self.assertEqual(der.encode_number(127), b("\x7f"))
self.assertEqual(der.encode_number(128), b("\x81\x00"))
self.assertEqual(der.encode_number(3*128+7), b("\x83\x07"))
#self.assertEqual(der.read_number("\x81\x9b"+"more"), (155, 2))
#self.assertEqual(der.encode_number(155), b("\x81\x9b"))
for n in (0, 1, 2, 127, 128, 3*128+7, 840, 10045): #, 155):
x = der.encode_number(n) + b("more")
n1, llen = der.read_number(x)
self.assertEqual(n1, n)
self.assertEqual(x[llen:], b("more"))
def test_length(self):
self.assertEqual(der.encode_length(0), b("\x00"))
self.assertEqual(der.encode_length(127), b("\x7f"))
self.assertEqual(der.encode_length(128), b("\x81\x80"))
self.assertEqual(der.encode_length(255), b("\x81\xff"))
self.assertEqual(der.encode_length(256), b("\x82\x01\x00"))
self.assertEqual(der.encode_length(3*256+7), b("\x82\x03\x07"))
self.assertEqual(der.read_length(b("\x81\x9b")+b("more")), (155, 2))
self.assertEqual(der.encode_length(155), b("\x81\x9b"))
for n in (0, 1, 2, 127, 128, 255, 256, 3*256+7, 155):
x = der.encode_length(n) + b("more")
n1, llen = der.read_length(x)
self.assertEqual(n1, n)
self.assertEqual(x[llen:], b("more"))
def test_sequence(self):
x = der.encode_sequence(b("ABC"), b("DEF")) + b("GHI")
self.assertEqual(x, b("\x30\x06ABCDEFGHI"))
x1, rest = der.remove_sequence(x)
self.assertEqual(x1, b("ABCDEF"))
self.assertEqual(rest, b("GHI"))
def test_constructed(self):
x = der.encode_constructed(0, NIST224p.encoded_oid)
self.assertEqual(hexlify(x), b("a007") + b("06052b81040021"))
x = der.encode_constructed(1, unhexlify(b("0102030a0b0c")))
self.assertEqual(hexlify(x), b("a106") + b("0102030a0b0c"))
class Util(unittest.TestCase):
def test_trytryagain(self):
tta = util.randrange_from_seed__trytryagain
for i in range(1000):
seed = "seed-%d" % i
for order in (2**8-2, 2**8-1, 2**8, 2**8+1, 2**8+2,
2**16-1, 2**16+1):
n = tta(seed, order)
self.assertTrue(1 <= n < order, (1, n, order))
# this trytryagain *does* provide long-term stability
self.assertEqual(("%x"%(tta("seed", NIST224p.order))).encode(),
b("6fa59d73bf0446ae8743cf748fc5ac11d5585a90356417e97155c3bc"))
def test_randrange(self):
# util.randrange does not provide long-term stability: we might
# change the algorithm in the future.
for i in range(1000):
entropy = util.PRNG("seed-%d" % i)
for order in (2**8-2, 2**8-1, 2**8,
2**16-1, 2**16+1,
):
# that oddball 2**16+1 takes half our runtime
n = util.randrange(order, entropy=entropy)
self.assertTrue(1 <= n < order, (1, n, order))
def OFF_test_prove_uniformity(self):
order = 2**8-2
counts = dict([(i, 0) for i in range(1, order)])
assert 0 not in counts
assert order not in counts
for i in range(1000000):
seed = "seed-%d" % i
n = util.randrange_from_seed__trytryagain(seed, order)
counts[n] += 1
# this technique should use the full range
self.assertTrue(counts[order-1])
for i in range(1, order):
print_("%3d: %s" % (i, "*"*(counts[i]//100)))
class RFC6979(unittest.TestCase):
# https://tools.ietf.org/html/rfc6979#appendix-A.1
def _do(self, generator, secexp, hsh, hash_func, expected):
actual = rfc6979.generate_k(generator.order(), secexp, hash_func, hsh)
self.assertEqual(expected, actual)
def test_SECP256k1(self):
'''RFC doesn't contain test vectors for SECP256k1 used in bitcoin.
This vector has been computed by Golang reference implementation instead.'''
self._do(
generator = SECP256k1.generator,
secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16),
hsh = sha256(b("sample")).digest(),
hash_func = sha256,
expected = int("8fa1f95d514760e498f28957b824ee6ec39ed64826ff4fecc2b5739ec45b91cd", 16))
def test_SECP256k1_2(self):
self._do(
generator=SECP256k1.generator,
secexp=int("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", 16),
hsh=sha256(b("sample")).digest(),
hash_func=sha256,
expected=int("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3", 16))
def test_SECP256k1_3(self):
self._do(
generator=SECP256k1.generator,
secexp=0x1,
hsh=sha256(b("Satoshi Nakamoto")).digest(),
hash_func=sha256,
expected=0x8F8A276C19F4149656B280621E358CCE24F5F52542772691EE69063B74F15D15)
def test_SECP256k1_4(self):
self._do(
generator=SECP256k1.generator,
secexp=0x1,
hsh=sha256(b("All those moments will be lost in time, like tears in rain. Time to die...")).digest(),
hash_func=sha256,
expected=0x38AA22D72376B4DBC472E06C3BA403EE0A394DA63FC58D88686C611ABA98D6B3)
def test_SECP256k1_5(self):
self._do(
generator=SECP256k1.generator,
secexp=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140,
hsh=sha256(b("Satoshi Nakamoto")).digest(),
hash_func=sha256,
expected=0x33A19B60E25FB6F4435AF53A3D42D493644827367E6453928554F43E49AA6F90)
def test_SECP256k1_6(self):
self._do(
generator=SECP256k1.generator,
secexp=0xf8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181,
hsh=sha256(b("Alan Turing")).digest(),
hash_func=sha256,
expected=0x525A82B70E67874398067543FD84C83D30C175FDC45FDEEE082FE13B1D7CFDF1)
def test_1(self):
# Basic example of the RFC, it also tests 'try-try-again' from Step H of rfc6979
self._do(
generator = Point(None, 0, 0, int("4000000000000000000020108A2E0CC0D99F8A5EF", 16)),
secexp = int("09A4D6792295A7F730FC3F2B49CBC0F62E862272F", 16),
hsh = unhexlify(b("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF")),
hash_func = sha256,
expected = int("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16))
def test_2(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha1(b("sample")).digest(),
hash_func = sha1,
expected = int("37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", 16))
def test_3(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha256(b("sample")).digest(),
hash_func = sha256,
expected = int("32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", 16))
def test_4(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha512(b("sample")).digest(),
hash_func = sha512,
expected = int("A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", 16))
def test_5(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha1(b("test")).digest(),
hash_func = sha1,
expected = int("D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", 16))
def test_6(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha256(b("test")).digest(),
hash_func = sha256,
expected = int("5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", 16))
def test_7(self):
self._do(
generator=NIST192p.generator,
secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16),
hsh = sha512(b("test")).digest(),
hash_func = sha512,
expected = int("0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", 16))
def test_8(self):
self._do(
generator=NIST521p.generator,
secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
hsh = sha1(b("sample")).digest(),
hash_func = sha1,
expected = int("089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D0F9", 16))
def test_9(self):
self._do(
generator=NIST521p.generator,
secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
hsh = sha256(b("sample")).digest(),
hash_func = sha256,
expected = int("0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C32575761793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E1A0", 16))
def test_10(self):
self._do(
generator=NIST521p.generator,
secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16),
hsh = sha512(b("test")).digest(),
hash_func = sha512,
expected = int("16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC56D", 16))
def __main__():
unittest.main()
if __name__ == "__main__":
__main__()

247
bin/python/ecdsa/util.py Normal file
View File

@@ -0,0 +1,247 @@
from __future__ import division
import os
import math
import binascii
from hashlib import sha256
from . import der
from .curves import orderlen
from .six import PY3, int2byte, b, next
# RFC5480:
# The "unrestricted" algorithm identifier is:
# id-ecPublicKey OBJECT IDENTIFIER ::= {
# iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
oid_ecPublicKey = (1, 2, 840, 10045, 2, 1)
encoded_oid_ecPublicKey = der.encode_oid(*oid_ecPublicKey)
def randrange(order, entropy=None):
"""Return a random integer k such that 1 <= k < order, uniformly
distributed across that range. For simplicity, this only behaves well if
'order' is fairly close (but below) a power of 256. The try-try-again
algorithm we use takes longer and longer time (on average) to complete as
'order' falls, rising to a maximum of avg=512 loops for the worst-case
(256**k)+1 . All of the standard curves behave well. There is a cutoff at
10k loops (which raises RuntimeError) to prevent an infinite loop when
something is really broken like the entropy function not working.
Note that this function is not declared to be forwards-compatible: we may
change the behavior in future releases. The entropy= argument (which
should get a callable that behaves like os.urandom) can be used to
achieve stability within a given release (for repeatable unit tests), but
should not be used as a long-term-compatible key generation algorithm.
"""
# we could handle arbitrary orders (even 256**k+1) better if we created
# candidates bit-wise instead of byte-wise, which would reduce the
# worst-case behavior to avg=2 loops, but that would be more complex. The
# change would be to round the order up to a power of 256, subtract one
# (to get 0xffff..), use that to get a byte-long mask for the top byte,
# generate the len-1 entropy bytes, generate one extra byte and mask off
# the top bits, then combine it with the rest. Requires jumping back and
# forth between strings and integers a lot.
if entropy is None:
entropy = os.urandom
assert order > 1
bytes = orderlen(order)
dont_try_forever = 10000 # gives about 2**-60 failures for worst case
while dont_try_forever > 0:
dont_try_forever -= 1
candidate = string_to_number(entropy(bytes)) + 1
if 1 <= candidate < order:
return candidate
continue
raise RuntimeError("randrange() tried hard but gave up, either something"
" is very wrong or you got realllly unlucky. Order was"
" %x" % order)
class PRNG:
# this returns a callable which, when invoked with an integer N, will
# return N pseudorandom bytes. Note: this is a short-term PRNG, meant
# primarily for the needs of randrange_from_seed__trytryagain(), which
# only needs to run it a few times per seed. It does not provide
# protection against state compromise (forward security).
def __init__(self, seed):
self.generator = self.block_generator(seed)
def __call__(self, numbytes):
a = [next(self.generator) for i in range(numbytes)]
if PY3:
return bytes(a)
else:
return "".join(a)
def block_generator(self, seed):
counter = 0
while True:
for byte in sha256(("prng-%d-%s" % (counter, seed)).encode()).digest():
yield byte
counter += 1
def randrange_from_seed__overshoot_modulo(seed, order):
# hash the data, then turn the digest into a number in [1,order).
#
# We use David-Sarah Hopwood's suggestion: turn it into a number that's
# sufficiently larger than the group order, then modulo it down to fit.
# This should give adequate (but not perfect) uniformity, and simple
# code. There are other choices: try-try-again is the main one.
base = PRNG(seed)(2*orderlen(order))
number = (int(binascii.hexlify(base), 16) % (order-1)) + 1
assert 1 <= number < order, (1, number, order)
return number
def lsb_of_ones(numbits):
return (1 << numbits) - 1
def bits_and_bytes(order):
bits = int(math.log(order-1, 2)+1)
bytes = bits // 8
extrabits = bits % 8
return bits, bytes, extrabits
# the following randrange_from_seed__METHOD() functions take an
# arbitrarily-sized secret seed and turn it into a number that obeys the same
# range limits as randrange() above. They are meant for deriving consistent
# signing keys from a secret rather than generating them randomly, for
# example a protocol in which three signing keys are derived from a master
# secret. You should use a uniformly-distributed unguessable seed with about
# curve.baselen bytes of entropy. To use one, do this:
# seed = os.urandom(curve.baselen) # or other starting point
# secexp = ecdsa.util.randrange_from_seed__trytryagain(sed, curve.order)
# sk = SigningKey.from_secret_exponent(secexp, curve)
def randrange_from_seed__truncate_bytes(seed, order, hashmod=sha256):
# hash the seed, then turn the digest into a number in [1,order), but
# don't worry about trying to uniformly fill the range. This will lose,
# on average, four bits of entropy.
bits, bytes, extrabits = bits_and_bytes(order)
if extrabits:
bytes += 1
base = hashmod(seed).digest()[:bytes]
base = "\x00"*(bytes-len(base)) + base
number = 1+int(binascii.hexlify(base), 16)
assert 1 <= number < order
return number
def randrange_from_seed__truncate_bits(seed, order, hashmod=sha256):
# like string_to_randrange_truncate_bytes, but only lose an average of
# half a bit
bits = int(math.log(order-1, 2)+1)
maxbytes = (bits+7) // 8
base = hashmod(seed).digest()[:maxbytes]
base = "\x00"*(maxbytes-len(base)) + base
topbits = 8*maxbytes - bits
if topbits:
base = int2byte(ord(base[0]) & lsb_of_ones(topbits)) + base[1:]
number = 1+int(binascii.hexlify(base), 16)
assert 1 <= number < order
return number
def randrange_from_seed__trytryagain(seed, order):
# figure out exactly how many bits we need (rounded up to the nearest
# bit), so we can reduce the chance of looping to less than 0.5 . This is
# specified to feed from a byte-oriented PRNG, and discards the
# high-order bits of the first byte as necessary to get the right number
# of bits. The average number of loops will range from 1.0 (when
# order=2**k-1) to 2.0 (when order=2**k+1).
assert order > 1
bits, bytes, extrabits = bits_and_bytes(order)
generate = PRNG(seed)
while True:
extrabyte = b("")
if extrabits:
extrabyte = int2byte(ord(generate(1)) & lsb_of_ones(extrabits))
guess = string_to_number(extrabyte + generate(bytes)) + 1
if 1 <= guess < order:
return guess
def number_to_string(num, order):
l = orderlen(order)
fmt_str = "%0" + str(2*l) + "x"
string = binascii.unhexlify((fmt_str % num).encode())
assert len(string) == l, (len(string), l)
return string
def number_to_string_crop(num, order):
l = orderlen(order)
fmt_str = "%0" + str(2*l) + "x"
string = binascii.unhexlify((fmt_str % num).encode())
return string[:l]
def string_to_number(string):
return int(binascii.hexlify(string), 16)
def string_to_number_fixedlen(string, order):
l = orderlen(order)
assert len(string) == l, (len(string), l)
return int(binascii.hexlify(string), 16)
# these methods are useful for the sigencode= argument to SK.sign() and the
# sigdecode= argument to VK.verify(), and control how the signature is packed
# or unpacked.
def sigencode_strings(r, s, order):
r_str = number_to_string(r, order)
s_str = number_to_string(s, order)
return (r_str, s_str)
def sigencode_string(r, s, order):
# for any given curve, the size of the signature numbers is
# fixed, so just use simple concatenation
r_str, s_str = sigencode_strings(r, s, order)
return r_str + s_str
def sigencode_der(r, s, order):
return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))
# canonical versions of sigencode methods
# these enforce low S values, by negating the value (modulo the order) if above order/2
# see CECKey::Sign() https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L214
def sigencode_strings_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_strings(r, s, order)
def sigencode_string_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_string(r, s, order)
def sigencode_der_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_der(r, s, order)
def sigdecode_string(signature, order):
l = orderlen(order)
assert len(signature) == 2*l, (len(signature), 2*l)
r = string_to_number_fixedlen(signature[:l], order)
s = string_to_number_fixedlen(signature[l:], order)
return r, s
def sigdecode_strings(rs_strings, order):
(r_str, s_str) = rs_strings
l = orderlen(order)
assert len(r_str) == l, (len(r_str), l)
assert len(s_str) == l, (len(s_str), l)
r = string_to_number_fixedlen(r_str, order)
s = string_to_number_fixedlen(s_str, order)
return r, s
def sigdecode_der(sig_der, order):
#return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))
rs_strings, empty = der.remove_sequence(sig_der)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER sig: %s" %
binascii.hexlify(empty))
r, rest = der.remove_integer(rs_strings)
s, empty = der.remove_integer(rest)
if empty != b(""):
raise der.UnexpectedDER("trailing junk after DER numbers: %s" %
binascii.hexlify(empty))
return r, s

105
bin/python/ed25519.py Normal file
View File

@@ -0,0 +1,105 @@
import hashlib
b = 256
q = 2**255 - 19
l = 2**252 + 27742317777372353535851937790883648493
def H(m):
return hashlib.sha512(m).digest()
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
d = -121665 * inv(121666)
I = expmod(2,(q-1)/4,q)
def xrecover(y):
xx = (y*y-1) * inv(d*y*y+1)
x = expmod(xx,(q+3)/8,q)
if (x*x - xx) % q != 0: x = (x*I) % q
if x % 2 != 0: x = q-x
return x
By = 4 * inv(5)
Bx = xrecover(By)
B = [Bx % q,By % q]
def edwards(P,Q):
x1 = P[0]
y1 = P[1]
x2 = Q[0]
y2 = Q[1]
x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
return [x3 % q,y3 % q]
def scalarmult(P,e):
if e == 0: return [0,1]
Q = scalarmult(P,e/2)
Q = edwards(Q,Q)
if e & 1: Q = edwards(Q,P)
return Q
def encodeint(y):
bits = [(y >> i) & 1 for i in range(b)]
return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
def encodepoint(P):
x = P[0]
y = P[1]
bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1]
return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
def bit(h,i):
return (ord(h[i/8]) >> (i%8)) & 1
def publickey(sk):
h = H(sk)
a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
A = scalarmult(B,a)
return encodepoint(A)
def Hint(m):
h = H(m)
return sum(2**i * bit(h,i) for i in range(2*b))
def signature(m,sk,pk):
h = H(sk)
a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m)
R = scalarmult(B,r)
S = (r + Hint(encodepoint(R) + pk + m) * a) % l
return encodepoint(R) + encodeint(S)
def isoncurve(P):
x = P[0]
y = P[1]
return (-x*x + y*y - 1 - d*x*x*y*y) % q == 0
def decodeint(s):
return sum(2**i * bit(s,i) for i in range(0,b))
def decodepoint(s):
y = sum(2**i * bit(s,i) for i in range(0,b-1))
x = xrecover(y)
if x & 1 != bit(s,b-1): x = q-x
P = [x,y]
if not isoncurve(P): raise Exception("decoding point that is not on curve")
return P
def checkvalid(s,m,pk):
if len(s) != b/4: raise Exception("signature length is wrong")
if len(pk) != b/8: raise Exception("public-key length is wrong")
R = decodepoint(s[0:b/8])
A = decodepoint(pk)
S = decodeint(s[b/8:b/4])
h = Hint(encodepoint(R) + pk + m)
if scalarmult(B,S) != edwards(R,scalarmult(A,h)):
raise Exception("signature does not pass verification")

View File

@@ -0,0 +1,51 @@
# Constants from ripple/protocol/SField.h
# special types
STI_UNKNOWN = -2
STI_DONE = -1
STI_NOTPRESENT = 0
# # types (common)
STI_UINT16 = 1
STI_UINT32 = 2
STI_UINT64 = 3
STI_HASH128 = 4
STI_HASH256 = 5
STI_AMOUNT = 6
STI_VL = 7
STI_ACCOUNT = 8
# 9-13 are reserved
STI_OBJECT = 14
STI_ARRAY = 15
# types (uncommon)
STI_UINT8 = 16
STI_HASH160 = 17
STI_PATHSET = 18
STI_VECTOR256 = 19
# high level types
# cannot be serialized inside other types
STI_TRANSACTION = 10001
STI_LEDGERENTRY = 10002
STI_VALIDATION = 10003
STI_METADATA = 10004
def field_code(sti, name):
if sti < 16:
if name < 16:
bytes = [(sti << 4) + name]
else:
bytes = [sti << 4, name]
elif name < 16:
bytes = [name, sti]
else:
bytes = [0, sti, name]
return ''.join(chr(i) for i in bytes)
# Selected constants from SField.cpp
sfSequence = field_code(STI_UINT32, 4)
sfPublicKey = field_code(STI_VL, 1)
sfSigningPubKey = field_code(STI_VL, 3)
sfSignature = field_code(STI_VL, 6)

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env python
from hashlib import sha256
#
# Human strings are base-58 with a
# version prefix and a checksum suffix.
#
# Copied from ripple/protocol/RippleAddress.h
#
VER_NONE = 1
VER_NODE_PUBLIC = 28
VER_NODE_PRIVATE = 32
VER_ACCOUNT_ID = 0
VER_ACCOUNT_PUBLIC = 35
VER_ACCOUNT_PRIVATE = 34
VER_FAMILY_GENERATOR = 41
VER_FAMILY_SEED = 33
ALPHABET = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
VERSION_NAME = {
VER_NONE: 'VER_NONE',
VER_NODE_PUBLIC: 'VER_NODE_PUBLIC',
VER_NODE_PRIVATE: 'VER_NODE_PRIVATE',
VER_ACCOUNT_ID: 'VER_ACCOUNT_ID',
VER_ACCOUNT_PUBLIC: 'VER_ACCOUNT_PUBLIC',
VER_ACCOUNT_PRIVATE: 'VER_ACCOUNT_PRIVATE',
VER_FAMILY_GENERATOR: 'VER_FAMILY_GENERATOR',
VER_FAMILY_SEED: 'VER_FAMILY_SEED'
}
class Alphabet(object):
def __init__(self, radix, digit_to_char, char_to_digit):
self.radix = radix
self.digit_to_char = digit_to_char
self.char_to_digit = char_to_digit
def transcode_from(self, s, source_alphabet):
n, zero_count = source_alphabet._digits_to_number(s)
digits = []
while n > 0:
n, digit = divmod(n, self.radix)
digits.append(self.digit_to_char(digit))
s = ''.join(digits)
return self.digit_to_char(0) * zero_count + s[::-1]
def _digits_to_number(self, digits):
stripped = digits.lstrip(self.digit_to_char(0))
n = 0
for d in stripped:
n *= self.radix
n += self.char_to_digit(d)
return n, len(digits) - len(stripped)
_INVERSE_INDEX = dict((c, i) for (i, c) in enumerate(ALPHABET))
# In base 58 encoding, the digits come from the ALPHABET string.
BASE58 = Alphabet(len(ALPHABET), ALPHABET.__getitem__, _INVERSE_INDEX.get)
# In base 256 encoding, each digit is just a character between 0 and 255.
BASE256 = Alphabet(256, chr, ord)
def encode(b):
return BASE58.transcode_from(b, BASE256)
def decode(b):
return BASE256.transcode_from(b, BASE58)
def checksum(b):
"""Returns a 4-byte checksum of a binary."""
return sha256(sha256(b).digest()).digest()[:4]
def encode_version(ver, b):
"""Encodes a version encoding and a binary as human string."""
b = chr(ver) + b
return encode(b + checksum(b))
def decode_version(s):
"""Decodes a human base-58 string into its version encoding and binary."""
b = decode(s)
body, check = b[:-4], b[-4:]
assert check == checksum(body), ('Bad checksum for', s)
return ord(body[0]), body[1:]
def version_name(ver):
return VERSION_NAME.get(ver) or ('(unknown version %s)' % ver)
def check_version(version, expected):
if version != expected:
raise ValueError('Expected version %s but got %s' % (
version_name(version), version_name(expected)))

View File

@@ -0,0 +1,164 @@
#!/usr/bin/env python
from __future__ import print_function
import base64, os, random, struct, sys
import ed25519
import ecdsa
from ripple.util import Base58
from ripple.ledger import SField
ED25519_BYTE = chr(0xed)
WRAP_COLUMNS = 60
USAGE = """\
Usage:
create
Create a new master public/secret key pair.
check <key>
Check an existing key for validity.
sign <sequence> <validator-public> <master-secret>
Create a new signed manifest with the given sequence
number, validator public key, and master secret key.
"""
def prepend_length_byte(b):
assert len(b) <= 192, 'Too long'
return chr(len(b)) + b
def to_int32(i):
return struct.pack('>I', i)
#-----------------------------------------------------------
def make_seed(urandom=os.urandom):
# This is not used.
return urandom(16)
def make_ed25519_keypair(urandom=os.urandom):
private_key = urandom(32)
return private_key, ed25519.publickey(private_key)
def make_ecdsa_keypair():
# This is not used.
private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
# Can't be unit tested easily - need a mock for ecdsa.
vk = private_key.get_verifying_key()
sig = private_key.sign('message')
assert vk.verify(sig, 'message')
return private_key, vk
def make_seed_from_passphrase(passphrase):
# For convenience, like say testing against rippled we can hash a passphrase
# to get the seed. validation_create (Josh may have killed it by now) takes
# an optional arg, which can be a base58 encoded seed, or a passphrase.
return hashlib.sha512(passphrase).digest()[:16]
def make_manifest(public_key, validator_public_key, seq):
return ''.join([
SField.sfSequence,
to_int32(seq),
SField.sfPublicKey, # Master public key.
prepend_length_byte(public_key),
SField.sfSigningPubKey, # Ephemeral public key.
prepend_length_byte(validator_public_key)])
def sign_manifest(manifest, private_key, public_key):
sig = ed25519.signature('MAN\0' + manifest, private_key, public_key)
return manifest + SField.sfSignature + prepend_length_byte(sig)
def wrap(s, cols=WRAP_COLUMNS):
if s:
size = max((len(s) + cols - 1) / cols, 1)
w = len(s) / size
s = '\n'.join(s[i:i + w] for i in range(0, len(s), w))
return s
def create_ed_keys(urandom=os.urandom):
private_key, public_key = make_ed25519_keypair(urandom)
public_key_human = Base58.encode_version(
Base58.VER_NODE_PUBLIC, ED25519_BYTE + public_key)
private_key_human = Base58.encode_version(
Base58.VER_NODE_PRIVATE, private_key)
return public_key_human, private_key_human
def check_validator_public(v, validator_public_key):
Base58.check_version(v, Base58.VER_NODE_PUBLIC)
if len(validator_public_key) != 33:
raise ValueError('Validator key should be length 33, is %s' %
len(validator_public_key))
b = ord(validator_public_key[0])
if b not in (2, 3):
raise ValueError('First validator key byte must be 2 or 3, is %d' % b)
def check_master_secret(v, private_key):
Base58.check_version(v, Base58.VER_NODE_PRIVATE)
if len(private_key) != 32:
raise ValueError('Length of master secret should be 32, is %s' %
len(private_key))
def get_signature(seq, validator_public_key_human, private_key_human):
v, validator_public_key = Base58.decode_version(validator_public_key_human)
check_validator_public(v, validator_public_key)
v, private_key = Base58.decode_version(private_key_human)
check_master_secret(v, private_key)
pk = ed25519.publickey(private_key)
apk = ED25519_BYTE + pk
m = make_manifest(apk, validator_public_key, seq)
m1 = sign_manifest(m, private_key, pk)
return base64.b64encode(m1)
# Testable versions of functions.
def perform_create(urandom=os.urandom, print=print):
public, private = create_ed_keys(urandom)
print('[validator_keys]', public, '', '[master_secret]', private, sep='\n')
def perform_check(s, print=print):
version, b = Base58.decode_version(s)
print('version = ' + Base58.version_name(version))
print('decoded length = ' + str(len(b)))
assert Base58.encode_version(version, b) == s
def perform_sign(
seq, validator_public_key_human, private_key_human, print=print):
print('[validation_manifest]')
print(wrap(get_signature(
int(seq), validator_public_key_human, private_key_human)))
# Externally visible versions of functions.
def create():
perform_create()
def check(s):
perform_check(s)
def sign(seq, validator_public_key_human, private_key_human):
perform_sign(seq, validator_public_key_human, private_key_human)
def usage(*errors):
if errors:
print(*errors)
print(USAGE)
return not errors
_COMMANDS = dict((f.__name__, f) for f in (create, check, sign))
def run_command(args):
if not args:
return usage()
name = args[0]
command = _COMMANDS.get(name)
if not command:
return usage('No such command:', command)
try:
command(*args[1:])
except TypeError:
return usage('Wrong number of arguments for:', command)
return True

View File

@@ -0,0 +1,682 @@
#!/usr/bin/env python
"""
Test for setting ephemeral keys for the validator manifest.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import argparse
import contextlib
from contextlib import contextmanager
import json
import os
import platform
import shutil
import subprocess
import time
DELAY_WHILE_PROCESS_STARTS_UP = 1.5
ARGS = None
NOT_FOUND = -1 # not in log
ACCEPTED_NEW = 0 # added new manifest
ACCEPTED_UPDATE = 1 # replaced old manifest with new
UNTRUSTED = 2 # don't trust master key
STALE = 3 # seq is too old
REVOKED = 4 # revoked validator key
INVALID = 5 # invalid signature
MANIFEST_ACTION_STR_TO_ID = {
'NotFound': NOT_FOUND, # not found in log
'AcceptedNew': ACCEPTED_NEW,
'AcceptedUpdate': ACCEPTED_UPDATE,
'Untrusted': UNTRUSTED,
'Stale': STALE,
'Revoked': REVOKED,
'Invalid': INVALID,
}
MANIFEST_ACTION_ID_TO_STR = {
v: k for k, v in MANIFEST_ACTION_STR_TO_ID.items()
}
CONF_TEMPLATE = """
[server]
port_rpc
port_peer
port_wss_admin
[port_rpc]
port = {rpc_port}
ip = 127.0.0.1
admin = 127.0.0.1
protocol = https
[port_peer]
port = {peer_port}
ip = 0.0.0.0
protocol = peer
[port_wss_admin]
port = {wss_port}
ip = 127.0.0.1
admin = 127.0.0.1
protocol = wss
[node_size]
medium
[node_db]
type={node_db_type}
path={node_db_path}
open_files=2000
filter_bits=12
cache_mb=256
file_size_mb=8
file_size_mult=2
online_delete=256
advisory_delete=0
[database_path]
{db_path}
[debug_logfile]
{debug_logfile}
[sntp_servers]
time.windows.com
time.apple.com
time.nist.gov
pool.ntp.org
[ips]
r.ripple.com 51235
[ips_fixed]
{sibling_ip} {sibling_port}
[validators]
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
[validation_quorum]
3
[validation_seed]
{validation_seed}
#vaidation_public_key: {validation_public_key}
# Other rippled's trusting this validator need this key
[validator_keys]
{all_validator_keys}
[peer_private]
1
[overlay]
expire = 1
auto_connect = 1
[validation_manifest]
{validation_manifest}
[rpc_startup]
{{ "command": "log_level", "severity": "debug" }}
[ssl_verify]
0
"""
# End config template
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
@static_vars(rpc=5005, peer=51235, wss=6006)
def checkout_port_nums():
"""Returns a tuple of port nums for rpc, peer, and wss_admin"""
checkout_port_nums.rpc += 1
checkout_port_nums.peer += 1
checkout_port_nums.wss += 1
return (
checkout_port_nums.rpc,
checkout_port_nums.peer,
checkout_port_nums.wss
)
def is_windows():
return platform.system() == 'Windows'
def manifest_create():
"""returns dict with keys: 'validator_keys', 'master_secret'"""
to_run = ['python', ARGS.ripple_home + '/bin/python/Manifest.py', 'create']
r = subprocess.check_output(to_run)
result = {}
k = None
for l in r.splitlines():
l = l.strip()
if not l:
continue
elif l == '[validator_keys]':
k = l[1:-1]
elif l == '[master_secret]':
k = l[1:-1]
elif l.startswith('['):
raise ValueError(
'Unexpected key: {} from `manifest create`'.format(l))
else:
if not k:
raise ValueError('Value with no key')
result[k] = l
k = None
if k in result:
raise ValueError('Repeat key from `manifest create`: ' + k)
if len(result) != 2:
raise ValueError(
'Expected 2 keys from `manifest create` but got {} keys instead ({})'.
format(len(result), result))
return result
def sign_manifest(seq, validation_pk, master_secret):
"""returns the signed manifest as a string"""
to_run = ['python', ARGS.ripple_home + '/bin/python/Manifest.py', 'sign',
str(seq), validation_pk, master_secret]
try:
r = subprocess.check_output(to_run)
except subprocess.CalledProcessError as e:
print('Error in sign_manifest: ', e.output)
raise e
result = []
for l in r.splitlines():
l.strip()
if not l or l == '[validation_manifest]':
continue
result.append(l)
return '\n'.join(result)
def get_ripple_exe():
"""Find the rippled executable"""
prefix = ARGS.ripple_home + '/build/'
exe = ['rippled', 'RippleD.exe']
to_test = [prefix + t + '.debug/' + e
for t in ['clang', 'gcc', 'msvc'] for e in exe]
for e in exe:
to_test.append(prefix + '/' + e)
for t in to_test:
if os.path.isfile(t):
return t
class RippledServer(object):
def __init__(self, exe, config_file, server_out):
self.config_file = config_file
self.exe = exe
self.process = None
self.server_out = server_out
self.reinit(config_file)
def reinit(self, config_file):
self.config_file = config_file
self.to_run = [self.exe, '--verbose', '--conf', self.config_file]
@property
def config_root(self):
return os.path.dirname(self.config_file)
@property
def master_secret_file(self):
return self.config_root + '/master_secret.txt'
def startup(self):
if ARGS.verbose:
print('starting rippled:' + self.config_file)
fout = open(self.server_out, 'w')
self.process = subprocess.Popen(
self.to_run, stdout=fout, stderr=subprocess.STDOUT)
def shutdown(self):
if not self.process:
return
fout = open(os.devnull, 'w')
subprocess.Popen(
self.to_run + ['stop'], stdout=fout, stderr=subprocess.STDOUT)
self.process.wait()
self.process = None
def rotate_logfile(self):
if self.server_out == os.devnull:
return
for i in range(100):
backup_name = '{}.{}'.format(self.server_out, i)
if not os.path.exists(backup_name):
os.rename(self.server_out, backup_name)
return
raise ValueError('Could not rotate logfile: {}'.
format(self.server_out))
def validation_create(self):
"""returns dict with keys:
'validation_key', 'validation_public_key', 'validation_seed'
"""
to_run = [self.exe, '-q', '--conf', self.config_file,
'--', 'validation_create']
try:
return json.loads(subprocess.check_output(to_run))['result']
except subprocess.CalledProcessError as e:
print('Error in validation_create: ', e.output)
raise e
@contextmanager
def rippled_server(config_file, server_out=os.devnull):
"""Start a ripple server"""
try:
server = None
server = RippledServer(ARGS.ripple_exe, config_file, server_out)
server.startup()
yield server
finally:
if server:
server.shutdown()
@contextmanager
def pause_server(server, config_file):
"""Shutdown and then restart a ripple server"""
try:
server.shutdown()
server.rotate_logfile()
yield server
finally:
server.reinit(config_file)
server.startup()
def parse_date(d, t):
"""Return the timestamp of a line, or none if the line has no timestamp"""
try:
return time.strptime(d+' '+t, '%Y-%B-%d %H:%M:%S')
except:
return None
def to_dict(l):
"""Given a line of the form Key0: Value0;Key2: Valuue2; Return a dict"""
fields = l.split(';')
result = {}
for f in fields:
if f:
v = f.split(':')
assert len(v) == 2
result[v[0].strip()] = v[1].strip()
return result
def check_ephemeral_key(validator_key,
log_file,
seq,
change_time):
"""
Detect when a server is informed of a validator's ephemeral key change.
`change_time` and `seq` may be None, in which case they are ignored.
"""
manifest_prefix = 'Manifest:'
# a manifest line has the form Manifest: action; Key: value;
# Key can be Pk (public key), Seq, OldSeq,
for l in open(log_file):
sa = l.split()
if len(sa) < 5 or sa[4] != manifest_prefix:
continue
d = to_dict(' '.join(sa[4:]))
# check the seq number and validator_key
if d['Pk'] != validator_key:
continue
if seq is not None and int(d['Seq']) != seq:
continue
if change_time:
t = parse_date(sa[0], sa[1])
if not t or t < change_time:
continue
action = d['Manifest']
return MANIFEST_ACTION_STR_TO_ID[action]
return NOT_FOUND
def check_ephemeral_keys(validator_key,
log_files,
seq,
change_time=None,
timeout_s=60):
result = [NOT_FOUND for i in range(len(log_files))]
if timeout_s < 10:
sleep_time = 1
elif timeout_s < 60:
sleep_time = 5
else:
sleep_time = 10
n = timeout_s//sleep_time
if n == 0:
n = 1
start_time = time.time()
for _ in range(n):
for i, lf in enumerate(log_files):
if result[i] != NOT_FOUND:
continue
result[i] = check_ephemeral_key(validator_key,
lf,
seq,
change_time)
if result[i] != NOT_FOUND:
if all(r != NOT_FOUND for r in result):
return result
else:
server_dir = os.path.basename(os.path.dirname(log_files[i]))
if ARGS.verbose:
print('Check for {}: {}'.format(
server_dir, MANIFEST_ACTION_ID_TO_STR[result[i]]))
tsf = time.time() - start_time
if tsf > 20:
if ARGS.verbose:
print('Waiting for key to propigate: ', tsf)
time.sleep(sleep_time)
return result
def get_validator_key(config_file):
in_validator_keys = False
for l in open(config_file):
sl = l.strip()
if not in_validator_keys and sl == '[validator_keys]':
in_validator_keys = True
continue
if in_validator_keys:
if sl.startswith('['):
raise ValueError('ThisServer validator key not found')
if sl.startswith('#'):
continue
s = sl.split()
if len(s) == 2 and s[1] == 'ThisServer':
return s[0]
def new_config_ephemeral_key(
server, seq, rm_dbs=False, master_secret_file=None):
"""Generate a new ephemeral key, add to config, restart server"""
config_root = server.config_root
config_file = config_root + '/rippled.cfg'
db_dir = config_root + '/db'
if not master_secret_file:
master_secret_file = server.master_secret_file
with open(master_secret_file) as f:
master_secret = f.read()
v = server.validation_create()
signed = sign_manifest(seq, v['validation_public_key'], master_secret)
with pause_server(server, config_file):
if rm_dbs and os.path.exists(db_dir):
shutil.rmtree(db_dir)
os.makedirs(db_dir)
# replace the validation_manifest section with `signed`
bak = config_file + '.bak'
if is_windows() and os.path.isfile(bak):
os.remove(bak)
os.rename(config_file, bak)
in_manifest = False
with open(bak, 'r') as src:
with open(config_file, 'w') as out:
for l in src:
sl = l.strip()
if not in_manifest and sl == '[validation_manifest]':
in_manifest = True
elif in_manifest:
if sl.startswith('[') or sl.startswith('#'):
in_manifest = False
out.write(signed)
out.write('\n\n')
else:
continue
out.write(l)
return (bak, config_file)
def parse_args():
parser = argparse.ArgumentParser(
description=('Create config files for n validators')
)
parser.add_argument(
'--ripple_home', '-r',
default=os.sep.join(os.path.realpath(__file__).split(os.sep)[:-5]),
help=('Root directory of the ripple repo'), )
parser.add_argument('--num_validators', '-n',
default=2,
help=('Number of validators'), )
parser.add_argument('--conf', '-c', help=('rippled config file'), )
parser.add_argument('--out', '-o',
default='test_output',
help=('config root directory'), )
parser.add_argument(
'--existing', '-e',
action='store_true',
help=('use existing config files'), )
parser.add_argument(
'--generate', '-g',
action='store_true',
help=('generate conf files only'), )
parser.add_argument(
'--verbose', '-v',
action='store_true',
help=('verbose status reporting'), )
parser.add_argument(
'--quiet', '-q',
action='store_true',
help=('quiet status reporting'), )
return parser.parse_args()
def get_configs(manifest_seq):
global ARGS
ARGS.ripple_home = os.path.expanduser(ARGS.ripple_home)
n = int(ARGS.num_validators)
if n<2:
raise ValueError(
'Need at least 2 rippled servers. Specified: {}'.format(n))
config_root = ARGS.out
ARGS.ripple_exe = get_ripple_exe()
if not ARGS.ripple_exe:
raise ValueError('No Exe Found')
if ARGS.existing:
return [
os.path.abspath('{}/validator_{}/rippled.cfg'.format(config_root, i))
for i in range(n)
]
initial_config = ARGS.conf
manifests = [manifest_create() for i in range(n)]
port_nums = [checkout_port_nums() for i in range(n)]
with rippled_server(initial_config) as server:
time.sleep(DELAY_WHILE_PROCESS_STARTS_UP)
validations = [server.validation_create() for i in range(n)]
signed_manifests = [sign_manifest(manifest_seq,
v['validation_public_key'],
m['master_secret'])
for m, v in zip(manifests, validations)]
node_db_type = 'RocksDB' if not is_windows() else 'NuDB'
node_db_filename = node_db_type.lower()
config_files = []
for i, (m, v, s) in enumerate(zip(manifests, validations, signed_manifests)):
sibling_index = (i - 1) % len(manifests)
all_validator_keys = '\n'.join([
m['validator_keys'] + ' ThisServer',
manifests[sibling_index]['validator_keys'] + ' NextInRing'])
this_validator_dir = os.path.abspath(
'{}/validator_{}'.format(config_root, i))
db_path = this_validator_dir + '/db'
node_db_path = db_path + '/' + node_db_filename
log_path = this_validator_dir + '/log'
debug_logfile = log_path + '/debug.log'
rpc_port, peer_port, wss_port = port_nums[i]
sibling_ip = '127.0.0.1'
sibling_port = port_nums[sibling_index][1]
d = {
'validation_manifest': s,
'all_validator_keys': all_validator_keys,
'node_db_type': node_db_type,
'node_db_path': node_db_path,
'db_path': db_path,
'debug_logfile': debug_logfile,
'rpc_port': rpc_port,
'peer_port': peer_port,
'wss_port': wss_port,
'sibling_ip': sibling_ip,
'sibling_port': sibling_port,
}
d.update(m)
d.update(v)
for p in [this_validator_dir, db_path, log_path]:
if not os.path.exists(p):
os.makedirs(p)
config_files.append('{}/rippled.cfg'.format(this_validator_dir))
with open(config_files[-1], 'w') as f:
f.write(CONF_TEMPLATE.format(**d))
with open('{}/master_secret.txt'.format(this_validator_dir), 'w') as f:
f.write(m['master_secret'])
return config_files
def update_ephemeral_key(
server, new_seq, log_files,
expected=None, rm_dbs=False, master_secret_file=None,
restore_origional_conf=False, timeout_s=300):
if not expected:
expected = {}
change_time = time.gmtime()
back_conf, new_conf = new_config_ephemeral_key(
server,
new_seq,
rm_dbs,
master_secret_file
)
validator_key = get_validator_key(server.config_file)
start_time = time.time()
ck = check_ephemeral_keys(validator_key,
log_files,
seq=new_seq,
change_time=change_time,
timeout_s=timeout_s)
if ARGS.verbose:
print('Check finished: {} secs.'.format(int(time.time() - start_time)))
all_success = True
for i, r in enumerate(ck):
e = expected.get(i, UNTRUSTED)
server_dir = os.path.basename(os.path.dirname(log_files[i]))
status = 'OK' if e == r else 'FAIL'
print('{}: Server: {} Expected: {} Got: {}'.
format(status, server_dir,
MANIFEST_ACTION_ID_TO_STR[e], MANIFEST_ACTION_ID_TO_STR[r]))
all_success = all_success and (e == r)
if restore_origional_conf:
if is_windows() and os.path.isfile(new_conf):
os.remove(new_conf)
os.rename(back_conf, new_conf)
return all_success
def run_main():
global ARGS
ARGS = parse_args()
manifest_seq = 1
config_files = get_configs(manifest_seq)
if ARGS.generate:
return
if len(config_files) <= 1:
print('Script requires at least 2 servers. Actual #: {}'.
format(len(config_files)))
return
with contextlib.nested(*(rippled_server(c, os.path.dirname(c)+'/log.txt')
for c in config_files)) as servers:
log_files = [os.path.dirname(cf)+'/log.txt' for cf in config_files[1:]]
validator_key = get_validator_key(config_files[0])
start_time = time.time()
ck = check_ephemeral_keys(validator_key,
[log_files[0]],
seq=None,
timeout_s=60)
if ARGS.verbose:
print('Check finished: {} secs.'.format(
int(time.time() - start_time)))
if any(r == NOT_FOUND for r in ck):
print('FAIL: Initial key did not propigate to all servers')
return
manifest_seq += 2
expected = {i: UNTRUSTED for i in range(len(log_files))}
expected[0] = ACCEPTED_UPDATE
if not ARGS.quiet:
print('Testing key update')
kr = update_ephemeral_key(servers[0], manifest_seq, log_files, expected)
if not kr:
print('\nFail: Key Update Test. Exiting')
return
expected = {i: UNTRUSTED for i in range(len(log_files))}
expected[0] = STALE
if not ARGS.quiet:
print('Testing stale key')
kr = update_ephemeral_key(
servers[0], manifest_seq-1, log_files, expected, rm_dbs=True)
if not kr:
print('\nFail: Stale Key Test. Exiting')
return
expected = {i: UNTRUSTED for i in range(len(log_files))}
expected[0] = STALE
if not ARGS.quiet:
print('Testing stale key 2')
kr = update_ephemeral_key(
servers[0], manifest_seq, log_files, expected, rm_dbs=True)
if not kr:
print('\nFail: Stale Key Test. Exiting')
return
expected = {i: UNTRUSTED for i in range(len(log_files))}
expected[0] = REVOKED
if not ARGS.quiet:
print('Testing revoked key')
kr = update_ephemeral_key(
servers[0], 0xffffffff, log_files, expected, rm_dbs=True)
if not kr:
print('\nFail: Revoked Key Text. Exiting')
return
print('\nOK: All tests passed')
if __name__ == '__main__':
run_main()

View File

@@ -0,0 +1,47 @@
from __future__ import absolute_import, division, print_function
from ripple.util import Base58
from unittest import TestCase
BINARY = 'nN9kfUnKTf7PpgLG'
class test_Base58(TestCase):
def run_test(self, before, after):
self.assertEquals(Base58.decode(before), after)
self.assertEquals(Base58.encode(after), before)
def test_trivial(self):
self.run_test('', '')
def test_zeroes(self):
for before, after in (('', ''), ('abc', 'I\x8b')):
for i in range(1, 257):
self.run_test('r' * i + before, '\0' * i + after)
def test_single_digits(self):
for i, c in enumerate(Base58.ALPHABET):
self.run_test(c, chr(i))
def test_various(self):
# Test three random numbers.
self.run_test('88Mw', '\x88L\xed')
self.run_test(
'nN9kfUnKTf7PpgLG', '\x03\xdc\x9co\xdea\xefn\xd3\xb8\xe2\xc1')
self.run_test(
'zzWWb4C5p6kNrVa4fEBoZpZKd3XQLXch7QJbLCuLdoS1CWr8qdAZHEmwMiJy8Hwp',
'xN\x82\xfcQ\x1f\xb3~\xdf\xc7\xb37#\xc6~A\xe9\xf6-\x1f\xcb"\xfab'
'(\'\xccv\x9e\x85\xc3\xd1\x19\x941{\x8et\xfbS}\x86.k\x07\xb5\xb3')
def test_check(self):
self.assertEquals(Base58.checksum(BINARY), '\xaa\xaar\x9d')
def test_encode(self):
self.assertEquals(
Base58.encode_version(Base58.VER_ACCOUNT_PUBLIC, BINARY),
'sB49XwJgmdEZDo8LmYwki7FYkiaN7')
def test_decode(self):
ver, b = Base58.decode_version('sB49XwJgmdEZDo8LmYwki7FYkiaN7')
self.assertEquals(ver, Base58.VER_ACCOUNT_PUBLIC)
self.assertEquals(b, BINARY)

View File

@@ -0,0 +1,127 @@
from __future__ import absolute_import, division, print_function
from ripple.util import Sign
from ripple.util import Base58
from ripple.ledger import SField
from unittest import TestCase
BINARY = 'nN9kfUnKTf7PpgLG'
class test_Sign(TestCase):
SEQUENCE = 23
SIGNATURE = (
'JAAAABdxIe2DIKUZd9jDjKikknxnDfWCHkSXYZReFenvsmoVCdIw6nMhAnZ2dnZ2'
'dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJM'
'zqkBJwDz30b2SkxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA')
def setUp(self):
self.results = []
def print(self, *args, **kwds):
self.results.append([list(args), kwds])
def test_field_code(self):
self.assertEquals(SField.field_code(SField.STI_UINT32, 4), '$')
self.assertEquals(SField.field_code(SField.STI_VL, 1), 'q')
self.assertEquals(SField.field_code(SField.STI_VL, 3), 's')
self.assertEquals(SField.field_code(SField.STI_VL, 6), 'v')
def test_strvl(self):
self.assertEquals(Sign.prepend_length_byte(BINARY),
'\x10nN9kfUnKTf7PpgLG')
def urandom(self, bytes):
return '\5' * bytes
def test_make_seed(self):
self.assertEquals(Sign.make_seed(self.urandom),
'\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5')
def test_make_ed(self):
private, public = Sign.make_ed25519_keypair(self.urandom)
self.assertEquals(private,
'\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5'
'\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5\5')
self.assertEquals(public,
'nz\x1c\xdd)\xb0\xb7\x8f\xd1:\xf4\xc5Y\x8f\xef\xf4'
'\xef*\x97\x16n<\xa6\xf2\xe4\xfb\xfc\xcd\x80P[\xf1')
def test_make_manifest(self):
_, pk = Sign.make_ed25519_keypair(self.urandom)
m = Sign.make_manifest(pk, 'verify', 12345)
self.assertEquals(
m, '$\x00\x0009q nz\x1c\xdd)\xb0\xb7\x8f\xd1:\xf4\xc5Y\x8f\xef\xf4'
'\xef*\x97\x16n<\xa6\xf2\xe4\xfb\xfc\xcd\x80P[\xf1s\x06verify')
def test_sign_manifest(self):
sk, pk = Sign.make_ed25519_keypair(self.urandom)
s = Sign.sign_manifest('manifest', sk, pk)
self.assertEquals(
s, 'manifestv@\xe5\x84\xbe\xc4\x80N\xa0v"\xb2\x80A\x88\x06\xc0'
'\xd2\xbae\x92\x89\xa8\'!\xdd\x00\x88\x06s\xe0\xf74\xe3Yg\xad{$'
'\x17\xd3\x99\xaa\x16\xb0\xeaZ\xd7]\r\xb3\xdc\x1b\x8f\xc1Z\xdfHU'
'\xb5\x92\xac\x82jI\x02')
def test_wrap(self):
wrap = lambda s: Sign.wrap(s, 5)
self.assertEquals(wrap(''), '')
self.assertEquals(wrap('12345'), '12345')
self.assertEquals(wrap('123456'), '123\n456')
self.assertEquals(wrap('12345678'), '1234\n5678')
self.assertEquals(wrap('1234567890'), '12345\n67890')
self.assertEquals(wrap('12345678901'), '123\n456\n789\n01')
def test_create_ed_keys(self):
pkh, skh = Sign.create_ed_keys(self.urandom)
self.assertEquals(
pkh, 'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY')
self.assertEquals(
skh, 'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne')
def get_test_keypair(self):
public = (Base58.VER_NODE_PUBLIC, '\x02' + (32 * 'v'))
private = (Base58.VER_NODE_PRIVATE, 32 * 'k')
Sign.check_validator_public(*public)
Sign.check_master_secret(*private)
return (Base58.encode_version(*public), Base58.encode_version(*private))
def test_get_signature(self):
signature = Sign.get_signature(self.SEQUENCE, *self.get_test_keypair())
self.assertEquals(
signature,
'JAAAABdxIe2DIKUZd9jDjKikknxnDfWCHkSXYZReFenvsmoVCdIw6nMhAnZ2dnZ2'
'dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJM'
'zqkBJwDz30b2SkxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA')
def test_check(self):
public = Base58.encode_version(Base58.VER_NODE_PRIVATE, 32 * 'k')
Sign.perform_check(public, self.print)
self.assertEquals(self.results,
[[['version = VER_NODE_PRIVATE'], {}],
[['decoded length = 32'], {}]])
def test_create(self):
Sign.perform_create(self.urandom, self.print)
self.assertEquals(
self.results,
[[['[validator_keys]',
'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY',
'',
'[master_secret]',
'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne'],
{'sep': '\n'}]])
def test_sign(self):
public, private = self.get_test_keypair()
Sign.perform_sign(self.SEQUENCE, public, private, print=self.print)
self.assertEquals(
self.results,
[[['[validation_manifest]'], {}],
[['JAAAABdxIe2DIKUZd9jDjKikknxnDfWCHkSXYZReFenvsmo\n'
'VCdIw6nMhAnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn\n'
'Z2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJMzqkBJwDz30b2S\n'
'kxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA'],
{}]])

133
bin/stop-test.js Normal file
View File

@@ -0,0 +1,133 @@
/* -------------------------------- REQUIRES -------------------------------- */
var child = require("child_process");
var assert = require("assert");
/* --------------------------------- CONFIG --------------------------------- */
if (process.argv[2] == null) {
[
'Usage: ',
'',
' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`',
'',
' Launch rippled and stop it after n seconds for all n in [i, j}',
' For all even values of n launch rippled with `--fg`',
' For values of n where n % 3 == 0 launch rippled with `--fg`\n',
'Examples: ',
'',
' $ node bin/stop-test.js 5,10',
(' $ node bin/stop-test.js 1,4 ' +
'build/clang.debug/rippled $HOME/.confs/rippled.cfg')
]
.forEach(function(l){console.log(l)});
process.exit();
} else {
var testRange = process.argv[2].split(',').map(Number);
var rippledPath = process.argv[3] || 'build/rippled'
var rippledConf = process.argv[4] || 'rippled.cfg'
}
var options = {
env: process.env,
stdio: 'ignore' // we could dump the child io when it fails abnormally
};
// default args
var conf_args = ['--conf='+rippledConf];
var start_args = conf_args.concat([/*'--net'*/])
var stop_args = conf_args.concat(['stop']);
/* --------------------------------- HELPERS -------------------------------- */
function start(args) {
return child.spawn(rippledPath, args, options);
}
function stop(rippled) { child.execFile(rippledPath, stop_args, options)}
function secs_l8r(ms, f) {setTimeout(f, ms * 1000); }
function show_results_and_exit(results) {
console.log(JSON.stringify(results, undefined, 2));
process.exit();
}
var timeTakes = function (range) {
function sumRange(n) {return (n+1) * n /2}
var ret = sumRange(range[1]);
if (range[0] > 1) {
ret = ret - sumRange(range[0] - 1)
}
var stopping = (range[1] - range[0]) * 0.5;
return ret + stopping;
}
/* ---------------------------------- TEST ---------------------------------- */
console.log("Test will take ~%s seconds", timeTakes(testRange));
(function oneTest(n /* seconds */, results) {
if (n >= testRange[1]) {
// show_results_and_exit(results);
console.log(JSON.stringify(results, undefined, 2));
oneTest(testRange[0], []);
return;
}
var args = start_args;
if (n % 2 == 0) {args = args.concat(['--fg'])}
if (n % 3 == 0) {args = args.concat(['--net'])}
var result = {args: args, alive_for: n};
results.push(result);
console.log("\nLaunching `%s` with `%s` for %d seconds",
rippledPath, JSON.stringify(args), n);
rippled = start(args);
console.log("Rippled pid: %d", rippled.pid);
// defaults
var b4StopSent = false;
var stopSent = false;
var stop_took = null;
rippled.once('exit', function(){
if (!stopSent && !b4StopSent) {
console.warn('\nRippled exited itself b4 stop issued');
process.exit();
};
// The io handles close AFTER exit, may have implications for
// `stdio:'inherit'` option to `child.spawn`.
rippled.once('close', function() {
result.stop_took = (+new Date() - stop_took) / 1000; // seconds
console.log("Stopping after %d seconds took %s seconds",
n, result.stop_took);
oneTest(n+1, results);
});
});
secs_l8r(n, function(){
console.log("Stopping rippled after %d seconds", n);
// possible race here ?
// seems highly unlikely, but I was having issues at one point
b4StopSent=true;
stop_took = (+new Date());
// when does `exit` actually get sent?
stop();
stopSent=true;
// Sometimes we want to attach with a debugger.
if (process.env.ABORT_TESTS_ON_STALL != null) {
// We wait 30 seconds, and if it hasn't stopped, we abort the process
secs_l8r(30, function() {
if (result.stop_took == null) {
console.log("rippled has stalled");
process.exit();
};
});
}
})
}(testRange[0], []));

42
circle.yml Normal file
View File

@@ -0,0 +1,42 @@
machine:
services:
- docker
dependencies:
pre:
- sudo apt-add-repository -y 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main'
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:afrank/boost
- wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-get update -qq
- sudo apt-get purge -qq libboost1.48-dev
- sudo apt-get install -qq libboost1.57-all-dev
- sudo apt-get install -qq clang-3.4 gcc-4.8 libobjc-4.8-dev libgcc-4.8-dev libstdc++-4.8-dev libclang1-3.4 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 99 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
- sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.4 99 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-3.4
- gcc --version
- clang --version
test:
pre:
- scons clang.debug
override:
- | # create gdb script
echo "set env MALLOC_CHECK_=3" > script.gdb
echo "run" >> script.gdb
echo "backtrace full" >> script.gdb
# gdb --help
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args build/clang.debug/rippled --unittest
- npm install
# Use build/(gcc|clang).debug/rippled
- |
echo "exports.default_server_config = {\"rippled_path\" : \"$HOME/rippled/build/clang.debug/rippled\"};" > test/config.js
# Run integration tests
- npm test
post:
- ./Builds/Docker/build-ci.sh
- docker images
deployment:
docker:
branch: /.*/
commands:
- ./Builds/Docker/push-to-hub.sh

View File

@@ -1,19 +1,28 @@
VFALCO NOTE - This file appears to be unmaintained.
A list of rippled version numbers, and the Github pull requests they contain.
Critical protocol changes
-------------------------
Mon Apr 8 16:13:12 PDT 2013
* The JSON field "inLedger" changing to "ledger_index"
Previous
* The JSON field "metaData" changing to "meta".
* RPC ledger will no longer take "ledger", use "ledger_hash" or "ledger_index".
* "ledgerClose" events:
** "hash" DEPRECATED: use "ledger_hash"
** "seqNum" DEPRECATED: use "ledger_index"
** "closeTime" DEPRECATED: use "close" or "close_human"
* stream "rt_accounts" --> "accounts_proposed"
* stream "rt_transactions" --> "transactions_proposed"
* subscribe "username" --> "url_username"
* subscribe "password" --> "url_password"
0.28.0-b12: Includes pulls 836, 887, 902, 903 and 904.
0.28.0-b13: Includes pulls 906, 912, 913, 914 and 915.
0.28.0-b14: Includes pulls 907, 910, 922 and 923.
0.28.0-b15: Includes pulls 832, 870, 879, 883, 911, 916, 919, 920, 924, 925 and 928. FAILED pulls 909 and 926.
0.28.0-b16: Includes pulls 909, 926, 929, 931, 932, 935 and 934.
0.28.0-b17: Includes pulls 927, 939, 940, 943, 944, 945 and 949.
0.28.0-b18: Includes pulls 930, 946, 947, 948, 951, 952, 953, 954, 955, 956, 959, 960 and 962.
0.29.0-b19: Includes pulls 967, 969 and 971.
0.29.0-b20: Includes pulls 935, 942, 957, 958, 963, 964, 965, 966, 968, 972, 973, 974 and 975.
0.29.0-b21: Includes pulls 970 and 976.
0.28.1-b4: Includes pulls 968, 998, 1005, 1008, 1010, 1011 and 1012.
0.28.1-b6: Includes pulls 983, 984, 1013, 1023 and 1024.
0.28.1-b8: Includes pulls 988, 1009, 1014, 1019, 1029, 1031, 1033, 1034 and 1035.
0.28.1-b9: Includes pulls 1026, 1030, 1036, 1037, 1038, 1040, and 1041.
0.28.1-rc2: Includes pulls 1044
0.28.1-rc3: Includes pulls 1052 and 1055.
0.28.1: Includes pulls 1056, 1059 and 1062, 1063.
0.28.2-b1: Includes pulls 866, 1045, 1046, 1047, 1050, 1051, 1057
0.28.2-b2: Includes pulls 1058, 1061, 1064 and 1065
0.28.2-b3: Includes pulls 1066, 1067, 1068
0.28.2-b4: Includes pulls 1060, 1069, 1071, 1072, 1075 and 1076.
0.28.2-b5: Includes pulls 1073, 1074, 1081, 1083, 1084, 1087, 1089, 1090, 1091
0.28.2-b6: Includes pulls 1085, 1093, 1094, 1096, 1101, 1102, 1105
0.28.2-b7: Includes pulls 1077, 1080, 1086, 1095, 1098, 1106 and 1112.
0.28.2-b8: Includes pulls 1078, 1100, 1108, 1114, 1118, 1119 and 1121.
0.28.2-b9: Includes pulls 1053, 1109, 1111, 1117, 1122 and 1123.

16
doc/Docker.md Normal file
View File

@@ -0,0 +1,16 @@
# Rippled Docker Image
Rippled has a continuous deployment pipeline that turns every git commit into a
docker image for quick testing and deployment.
To run the tip of the latest release via docker:
```$ docker run -P -v /srv/rippled/ ripple/rippled:latest```
To run the tip of active development:
```$ docker run -P -v /srv/rippled/ ripple/rippled:develop```
Where ```/srv/rippled``` points to a directory containing a rippled.cfg and
database files. By default, port 5005/tcp maps to the RPC port and 51235/udp to
the peer port.

110
doc/manifest-tool-guide.md Normal file
View File

@@ -0,0 +1,110 @@
# Manifest Tool Guide
This guide explains how to setup a validator so the key pairs used to sign and
verify validations may safely change. This procedure does not require manual
reconfiguration of servers that trust this validator.
Validators use two types of key pairs: *master keys* and *ephemeral
keys*. Ephemeral keys are used to sign and verify validations. Master keys are
used to sign and verify manifests that change ephemeral keys. The master secret
key should be tightly controlled. The ephemeral secret key needs to be present
in the config file.
## Validator Keys
When first setting up a validator, use the `manifest` script to generate a
master key pair:
```
$ bin/manifest create
```
Sample output:
```
[validator_keys]
nHUSSzGw4A9zEmFtK2Q2NcWDH9xmGdXMHc1MsVej3QkLTgvDNeBr
[master_secret]
pnxayCakmZRQE2qhEVRbFjiWCunReSbN1z64vPL36qwyLgogyYc
```
The first value is the master public key. Add the public key to the config
for this validator. A one-word comment must be added after the key (for example
*ThisServersName*). Any other rippled trusting the validator needs to add the
master public key to its config. Only add keys received from trusted sources.
The second value is the corresponding master secret key. **DO NOT INSTALL THIS
IN THE CONFIG**. The master secret key will be used to sign manifests that
change validation keys. Put the master secret key in a secure but recoverable
location.
## Validation Keys
When first setting up a validator, or when changing the ephemeral keys, use the
`rippled` program to create a new ephemeral key pair:
```
$ rippled validation_create
```
Sample output:
```
Loading: "/Users/alice/.config/ripple/rippled.cfg"
Securely connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"validation_key" : "TOO EDNA SHUN FEUD STAB JOAN BIAS FLEA WISE BOHR LOSS WEEK",
"validation_public_key" : "n9JzKV3ZrcZ3DW5pwjakj4hpijJ9oMiyrPDGJc3mpsndL6Gf3zwd",
"validation_seed" : "sahzkAajS2dyhjXg2yovjdZhXmjsx"
}
}
```
Add the `validation_seed` value (the ephemeral secret key) to this validator's
config. It is recommended to add the ephemeral public key and the sequence
number as a comment as well (sequence numbers are be explained below):
```
[validation_seed]
sahzkAajS2dyhjXg2yovjdZhXmjsx
# validation_public_key: n9JzKV3ZrcZ3DW5pwjakj4hpijJ9oMiyrPDGJc3mpsndL6Gf3zwd
# sequence number: 1
```
A manifest is a signed message used to inform other servers of this validator's
ephemeral public key. A manifest contains a sequence number, the new ephemeral
public key, and it is signed with the master secret key. The sequence number
should be higher than the previous sequence number (if it is not, the manifest
will be ignored). Usually the previous sequence number will be incremented by
one. Use the `manifest` script to create a manifest. It has the form:
```
$ bin/manifest sign sequence_number validation_public_key master_secret
```
For example:
```
$ bin/manifest sign 1 n9JzKV3Z...L6Gf3zwd pnxayCak...yLgogyYc
```
Sample output:
```
[validation_manifest]
JAAAAAFxIe2PEzNhe996gykB1PJQNoDxvr/Y0XhDELw8d/i
Fcgz3A3MhAjqhKsgZTmK/3BPEI+kzjV1p9ip7pl/AtF7CKd
NSfAH9dkCxezV6apS4FLYzAcQilONx315HvebwAB/pLPaM4
2sWCEppSuLNKN/JJjTABOo9tmAiNnnstF83yvecKMJzniwN
```
Copy this to the config for this validator. Don't forget to update the comment
noting the sequence number.
## Revoking a key
If a master key is compromised, the key may be revoked permanently. To revoke a
master key, sign a manifest with the highest possible sequence number:
`4,294,967,295`

File diff suppressed because it is too large Load Diff

BIN
images/build.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/contribute.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
images/pathfinding.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Some files were not shown because too many files have changed in this diff Show More