diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index d3ed26dc82..742bdc313d 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -597,12 +597,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -1207,6 +1201,12 @@
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -1249,6 +1249,12 @@
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -2265,7 +2271,6 @@
-
@@ -2411,6 +2416,7 @@
+
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index 2f94121c57..b6f2a7756b 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -1386,15 +1386,18 @@
[2] Old Ripple\ripple_app\ledger
-
- [1] Ripple\rpc\impl
-
[2] Old Ripple\ripple_app\main
[2] Old Ripple\ripple_app\peers
+
+ [2] Old Ripple\ripple_app\shamap
+
+
+ [2] Old Ripple\ripple_app\shamap
+
@@ -2859,15 +2862,15 @@
[1] Ripple\algorithm\api
-
- [1] Ripple\rpc\api
-
[2] Old Ripple\ripple_app\main
[2] Old Ripple\ripple_app\peers
+
+ [2] Old Ripple\ripple_app\shamap
+
diff --git a/src/ripple_app/ripple_app_pt2.cpp b/src/ripple_app/ripple_app_pt2.cpp
index 123a9fe6e2..4a95053cba 100644
--- a/src/ripple_app/ripple_app_pt2.cpp
+++ b/src/ripple_app/ripple_app_pt2.cpp
@@ -43,3 +43,7 @@ namespace ripple {
#include "data/DBInit.cpp"
}
+
+# include "shamap/RadixMapTest.h"
+#include "shamap/RadixMapTest.cpp"
+#include "shamap/FetchPackTests.cpp"
diff --git a/src/ripple_app/shamap/FetchPackTests.cpp b/src/ripple_app/shamap/FetchPackTests.cpp
new file mode 100644
index 0000000000..bfb17bb289
--- /dev/null
+++ b/src/ripple_app/shamap/FetchPackTests.cpp
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 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.
+*/
+//==============================================================================
+
+namespace ripple {
+
+class FetchPackTests : public UnitTest
+{
+public:
+ enum
+ {
+ tableItems = 100,
+ tableItemsExtra = 20
+ };
+
+ typedef boost::unordered_map Map;
+
+ struct TestFilter : SHAMapSyncFilter
+ {
+ TestFilter (Map& map, Journal journal) : mMap (map), mJournal (journal)
+ {
+ }
+
+ void gotNode (bool fromFilter,
+ SHAMapNode const& id, uint256 const& nodeHash,
+ Blob& nodeData, SHAMapTreeNode::TNType type)
+ {
+ }
+
+ bool haveNode (SHAMapNode const& id,
+ uint256 const& nodeHash, Blob& nodeData)
+ {
+ Map::iterator it = mMap.find (nodeHash);
+ if (it == mMap.end ())
+ {
+ mJournal.fatal << "Test filter missing node";
+ return false;
+ }
+ nodeData = it->second;
+ return true;
+ }
+
+ Map& mMap;
+ Journal mJournal;
+ };
+
+
+ void on_fetch (Map& map, uint256 const& hash, Blob const& blob)
+ {
+ Serializer s (blob);
+ expect (s.getSHA512Half() == hash, "Hash mismatch");
+ map.emplace (hash, blob);
+ }
+
+ void runTest ()
+ {
+ using namespace RadixMap;
+
+ beginTestCase ("Build");
+
+ shared_ptr t1 (beast::make_shared (smtFREE));
+ add_random_items (tableItems, *t1, random());
+ shared_ptr t2 (t1->snapShot (true));
+
+ add_random_items (tableItemsExtra, *t1, random ());
+ add_random_items (tableItemsExtra, *t2, random ());
+
+ // turn t1 into t2
+ Map map;
+ t2->getFetchPack (t1.get(), true, 1000000, boost::bind (
+ &FetchPackTests::on_fetch, this, boost::ref (map), _1, _2));
+ t1->getFetchPack (nullptr, true, 1000000, boost::bind (
+ &FetchPackTests::on_fetch, this, boost::ref (map), _1, _2));
+
+ // try to rebuild t2 from the fetch pack
+ shared_ptr t3;
+ try
+ {
+ TestFilter filter (map, journal ());
+
+ t3 = beast::make_shared (smtFREE, t2->getHash () );
+
+ expect (t3->fetchRoot (t2->getHash (), &filter), "unable to get root");
+
+ // everything should be in the pack, no hashes should be needed
+ std::vector hashes = t3->getNeededHashes(1, &filter);
+ expect (hashes.empty(), "missing hashes");
+ }
+ catch (...)
+ {
+ journal().fatal << "exception";
+ fail ();
+ }
+
+ expect (t3->getHash () == t2->getHash (), "root hashes do not match");
+ expect (t3->deepCompare (*t2), "failed compare");
+
+ pass ();
+ }
+
+ FetchPackTests () : UnitTest ("FetchPack", "ripple")
+ {
+ }
+};
+
+static FetchPackTests fetchPackTests;
+
+}
diff --git a/src/ripple_app/shamap/RadixMapTest.cpp b/src/ripple_app/shamap/RadixMapTest.cpp
new file mode 100644
index 0000000000..36eeb838ee
--- /dev/null
+++ b/src/ripple_app/shamap/RadixMapTest.cpp
@@ -0,0 +1,46 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 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.
+*/
+//==============================================================================
+
+namespace ripple {
+namespace RadixMap {
+
+shared_ptr - make_random_item (Random& r)
+{
+ Serializer s;
+ for (int d = 0; d < 3; ++d)
+ s.add32 (r.nextInt ());
+ return beast::make_shared
- (
+ s.getRIPEMD160().to256(), s.peekData ());
+}
+
+//------------------------------------------------------------------------------
+
+void add_random_items (std::size_t n, Table& t, Random& r)
+{
+ while (n--)
+ {
+ shared_ptr item (
+ make_random_item (r));
+ meets_postcondition (
+ t.addItem (*item, false, false));
+ }
+}
+
+}
+}
diff --git a/src/ripple_app/shamap/RadixMapTest.h b/src/ripple_app/shamap/RadixMapTest.h
new file mode 100644
index 0000000000..a66af04d77
--- /dev/null
+++ b/src/ripple_app/shamap/RadixMapTest.h
@@ -0,0 +1,39 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 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.
+*/
+//==============================================================================
+
+namespace ripple {
+namespace RadixMap {
+
+typedef SHAMap Table;
+typedef SHAMapItem Item;
+
+// Utility functions for RadixMap::Table (a.k.a. SHAMap) unit tests
+
+/** Returns a pseudo random Table item. */
+shared_ptr
- make_random_item (Random& r);
+
+/** Adds a set of random items to the Table.
+ @param n The number of items to add.
+ @param t The table to add the items to.
+ @param r A pseudo random number generator.
+*/
+void add_random_items (std::size_t n, Table& t, Random& r);
+
+}
+}
diff --git a/src/ripple_app/shamap/SHAMap.cpp b/src/ripple_app/shamap/SHAMap.cpp
index d913de3d86..a3a84c3e8c 100644
--- a/src/ripple_app/shamap/SHAMap.cpp
+++ b/src/ripple_app/shamap/SHAMap.cpp
@@ -53,7 +53,6 @@ SHAMap::SHAMap (SHAMapType t, uint256 const& hash,
, mType (t)
, m_missing_node_handler (missing_node_handler)
{
- // FIXME: Need to acquire root node
if (t == smtSTATE)
mTNByID.rehash (STATE_MAP_BUCKETS);
diff --git a/src/ripple_app/shamap/SHAMapSync.cpp b/src/ripple_app/shamap/SHAMapSync.cpp
index 092b01b705..c524bab9c9 100644
--- a/src/ripple_app/shamap/SHAMapSync.cpp
+++ b/src/ripple_app/shamap/SHAMapSync.cpp
@@ -428,7 +428,7 @@ bool SHAMap::deepCompare (SHAMap& other)
}
else if (otherNode->getNodeHash () != node->getNodeHash ())
{
- WriteLog (lsWARNING, SHAMap) << "node hash mismatch";
+ WriteLog (lsWARNING, SHAMap) << "node hash mismatch " << *node;
return false;
}
@@ -657,7 +657,7 @@ public:
return boost::make_shared (s.getRIPEMD160 ().to256 (), s.peekData ());
}
- static bool confuseMap (SHAMap& map, int count)
+ bool confuseMap (SHAMap& map, int count)
{
// add a bunch of random states to a map, then remove them
// map should be the same
@@ -672,7 +672,8 @@ public:
if (!map.addItem (*item, false, false))
{
- WriteLog (lsFATAL, SHAMap) << "Unable to add item to map";
+ journal().fatal <<
+ "Unable to add item to map";
return false;
}
}
@@ -681,14 +682,16 @@ public:
{
if (!map.delItem (*it))
{
- WriteLog (lsFATAL, SHAMap) << "Unable to remove item from map";
+ journal().fatal <<
+ "Unable to remove item from map";
return false;
}
}
if (beforeHash != map.getHash ())
{
- WriteLog (lsFATAL, SHAMap) << "Hashes do not match";
+ journal().fatal <<
+ "Hashes do not match";
return false;
}