diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index fd6110a9d..86abbb60a 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -2365,6 +2365,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index e0e7611ba..a6b81c324 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -3096,6 +3096,9 @@
ripple\ledger\tests
+
+ ripple\ledger\tests
+
ripple\ledger\tests
diff --git a/src/ripple/ledger/tests/SkipList_test.cpp b/src/ripple/ledger/tests/SkipList_test.cpp
new file mode 100644
index 000000000..d1f5166a9
--- /dev/null
+++ b/src/ripple/ledger/tests/SkipList_test.cpp
@@ -0,0 +1,112 @@
+//-----------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+#include
+#include
+#include
+#include
+#include
+
+namespace ripple {
+namespace test {
+
+class SkipList_test : public beast::unit_test::suite
+{
+ void
+ testSkipList()
+ {
+ beast::Journal const j;
+ std::vector> history;
+ {
+ Config const config;
+ auto prev =
+ std::make_shared(create_genesis, config);
+ history.push_back(prev);
+ for (auto i = 0; i < 1023; ++i)
+ {
+ auto next = std::make_shared(
+ open_ledger, *prev);
+ next->updateSkipList();
+ next->setClosed();
+ history.push_back(next);
+ prev = next;
+ }
+ }
+
+ {
+ auto l = *(std::next(std::begin(history)));
+ expect((*std::begin(history))->info().seq <
+ l->info().seq);
+ expect(hashOfSeq(*l, l->info().seq + 1,
+ j) == boost::none);
+ expect(hashOfSeq(*l, l->info().seq,
+ j) == l->info().hash);
+ expect(hashOfSeq(*l, l->info().seq - 1,
+ j) == l->info().parentHash);
+ expect(hashOfSeq(*history.back(),
+ l->info().seq, j) == boost::none);
+ }
+
+ // ledger skip lists store up to the previous 256 hashes
+ for (auto i = history.crbegin();
+ i != history.crend(); i += 256)
+ {
+ for (auto n = i;
+ n != std::next(i,
+ (*i)->info().seq - 256 > 1 ? 257 : 256);
+ ++n)
+ {
+ expect(hashOfSeq(**i,
+ (*n)->info().seq, j) ==
+ (*n)->info().hash);
+ }
+
+ // edge case accessing beyond 256
+ expect(hashOfSeq(**i,
+ (*i)->info().seq - 258, j) ==
+ boost::none);
+ }
+
+ // every 256th hash beyond the first 256 is stored
+ for (auto i = history.crbegin();
+ i != std::next(history.crend(), -512);
+ i += 256)
+ {
+ for (auto n = std::next(i, 512);
+ n != history.crend();
+ n += 256)
+ {
+ expect(hashOfSeq(**i,
+ (*n)->info().seq, j) ==
+ (*n)->info().hash);
+ }
+ }
+ }
+
+ void run()
+ {
+ LogSquelcher l;
+ testSkipList();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(SkipList,ledger,ripple);
+
+} // test
+} // ripple
diff --git a/src/ripple/unity/ledger.cpp b/src/ripple/unity/ledger.cpp
index 9e9c4d14c..29a7b59b7 100644
--- a/src/ripple/unity/ledger.cpp
+++ b/src/ripple/unity/ledger.cpp
@@ -31,6 +31,7 @@
#include
#include
-#include
-#include
#include
+#include
+#include
+#include