Electroneum
ringdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <boost/filesystem.hpp>
35 
36 #include "gtest/gtest.h"
37 
38 #include "string_tools.h"
39 #include "crypto/crypto.h"
40 #include "crypto/random.h"
41 #include "crypto/chacha.h"
42 #include "ringct/rctOps.h"
44 #include "wallet/ringdb.h"
45 
46 static crypto::chacha_key generate_chacha_key()
47 {
48  crypto::chacha_key chacha_key;
49  uint64_t password = crypto::rand<uint64_t>();
50  crypto::generate_chacha_key(std::string((const char*)&password, sizeof(password)), chacha_key, 1);
51  return chacha_key;
52 }
53 
54 static crypto::key_image generate_key_image()
55 {
59  return key_image;
60 }
61 
62 static std::pair<uint64_t, uint64_t> generate_output()
63 {
64  return std::make_pair(rand(), rand());
65 }
66 
67 
68 static const crypto::chacha_key KEY_1 = generate_chacha_key();
69 static const crypto::chacha_key KEY_2 = generate_chacha_key();
70 static const crypto::key_image KEY_IMAGE_1 = generate_key_image();
71 static const std::pair<uint64_t, uint64_t> OUTPUT_1 = generate_output();
72 static const std::pair<uint64_t, uint64_t> OUTPUT_2 = generate_output();
73 
74 class RingDB: public tools::ringdb
75 {
76 public:
77  RingDB(const char *genesis = ""): tools::ringdb(make_filename(), genesis) { }
78  ~RingDB() { close(); boost::filesystem::remove_all(filename); free(filename); }
79 
80 private:
81  std::string make_filename()
82  {
83  boost::filesystem::path path =
84  boost::filesystem::temp_directory_path();
85 #if defined(__MINGW32__) || defined(__MINGW__)
86  filename = tempnam(path.string().c_str(), "electroneum-ringdb-test-");
87  EXPECT_TRUE(filename != NULL);
88 #else
89  path /= "electroneum-ringdb-test-XXXXXX";
90  filename = strdup(path.string().c_str());
91  EXPECT_TRUE(mkdtemp(filename) != NULL);
92 #endif
93  return filename;
94  }
95 
96 private:
97  char *filename;
98 };
99 
100 TEST(ringdb, not_found)
101 {
102  RingDB ringdb;
103  std::vector<uint64_t> outs;
104  ASSERT_FALSE(ringdb.get_ring(KEY_1, KEY_IMAGE_1, outs));
105 }
106 
107 TEST(ringdb, found)
108 {
109  RingDB ringdb;
110  std::vector<uint64_t> outs, outs2;
111  outs.push_back(43); outs.push_back(7320); outs.push_back(8429);
112  ASSERT_TRUE(ringdb.set_ring(KEY_1, KEY_IMAGE_1, outs, false));
113  ASSERT_TRUE(ringdb.get_ring(KEY_1, KEY_IMAGE_1, outs2));
114  ASSERT_EQ(outs, outs2);
115 }
116 
117 TEST(ringdb, convert)
118 {
119  RingDB ringdb;
120  std::vector<uint64_t> outs, outs2;
121  outs.push_back(43); outs.push_back(7320); outs.push_back(8429);
122  ASSERT_TRUE(ringdb.set_ring(KEY_1, KEY_IMAGE_1, outs, true));
123  ASSERT_TRUE(ringdb.get_ring(KEY_1, KEY_IMAGE_1, outs2));
124  ASSERT_EQ(outs2.size(), 3);
125  ASSERT_EQ(outs2[0], 43);
126  ASSERT_EQ(outs2[1], 43+7320);
127  ASSERT_EQ(outs2[2], 43+7320+8429);
128 }
129 
130 TEST(ringdb, different_genesis)
131 {
132  RingDB ringdb;
133  std::vector<uint64_t> outs, outs2;
134  outs.push_back(43); outs.push_back(7320); outs.push_back(8429);
135  ASSERT_TRUE(ringdb.set_ring(KEY_1, KEY_IMAGE_1, outs, false));
136  ASSERT_FALSE(ringdb.get_ring(KEY_2, KEY_IMAGE_1, outs2));
137 }
138 
139 TEST(spent_outputs, not_found)
140 {
141  RingDB ringdb;
142  ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
143  ASSERT_FALSE(ringdb.blackballed(OUTPUT_2));
144 }
145 
146 TEST(spent_outputs, found)
147 {
148  RingDB ringdb;
149  ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
150  ASSERT_TRUE(ringdb.blackballed(OUTPUT_1));
151 }
152 
153 TEST(spent_outputs, vector)
154 {
155  RingDB ringdb;
156  std::vector<std::pair<uint64_t, uint64_t>> outputs;
157  outputs.push_back(std::make_pair(0, 1));
158  outputs.push_back(std::make_pair(10, 3));
159  outputs.push_back(std::make_pair(10, 4));
160  outputs.push_back(std::make_pair(10, 8));
161  outputs.push_back(std::make_pair(20, 0));
162  outputs.push_back(std::make_pair(20, 1));
163  outputs.push_back(std::make_pair(30, 5));
164  ASSERT_TRUE(ringdb.blackball(outputs));
165  ASSERT_TRUE(ringdb.blackballed(std::make_pair(0, 1)));
166  ASSERT_FALSE(ringdb.blackballed(std::make_pair(10, 2)));
167  ASSERT_TRUE(ringdb.blackballed(std::make_pair(10, 3)));
168  ASSERT_TRUE(ringdb.blackballed(std::make_pair(10, 4)));
169  ASSERT_FALSE(ringdb.blackballed(std::make_pair(10, 5)));
170  ASSERT_TRUE(ringdb.blackballed(std::make_pair(10, 8)));
171  ASSERT_TRUE(ringdb.blackballed(std::make_pair(20, 0)));
172  ASSERT_TRUE(ringdb.blackballed(std::make_pair(20, 1)));
173  ASSERT_FALSE(ringdb.blackballed(std::make_pair(20, 2)));
174  ASSERT_TRUE(ringdb.blackballed(std::make_pair(30, 5)));
175 }
176 
177 TEST(spent_outputs, mark_as_unspent)
178 {
179  RingDB ringdb;
180  ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
181  ASSERT_TRUE(ringdb.unblackball(OUTPUT_1));
182  ASSERT_FALSE(ringdb.blackballed(OUTPUT_1));
183 }
184 
185 TEST(spent_outputs, clear)
186 {
187  RingDB ringdb;
188  ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
189  ASSERT_TRUE(ringdb.clear_blackballs());
190  ASSERT_FALSE(ringdb.blackballed(OUTPUT_1));
191 }
192 
std::vector< std::string > keypair
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
::std::string string
Definition: gtest-port.h:1097
bool unblackball(const std::pair< uint64_t, uint64_t > &output)
Definition: ringdb.cpp:477
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
RingDB(const char *genesis="")
Definition: ringdb.cpp:77
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image)
Definition: crypto.h:324
void rand(size_t N, uint8_t *bytes)
Definition: crypto.h:209
bool blackball(const std::pair< uint64_t, uint64_t > &output)
Definition: ringdb.cpp:471
Various Tools.
Definition: tools.cpp:31
bool get_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, std::vector< uint64_t > &outs)
Definition: ringdb.cpp:338
device & get_device(const std::string &device_descriptor)
Definition: device.cpp:95
unsigned __int64 uint64_t
Definition: stdint.h:136
ringdb(std::string filename, const std::string &genesis)
Definition: ringdb.cpp:200
static keypair generate(hw::device &hwdev)
bool blackballed(const std::pair< uint64_t, uint64_t > &output)
Definition: ringdb.cpp:483
POD_CLASS key_image
Definition: crypto.h:102
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
~RingDB()
Definition: ringdb.cpp:78
void close()
Definition: ringdb.cpp:242
bool clear_blackballs()
Definition: ringdb.cpp:489
bool set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector< uint64_t > &outs, bool relative)
Definition: ringdb.cpp:374
TEST(ringdb, not_found)
Definition: ringdb.cpp:100