1
0
forked from cheng/wallet

Merge branch 'master' of ../../wallet into docs

This commit is contained in:
Cheng 2023-05-16 08:09:44 +08:00
commit 8c07e05a82
No known key found for this signature in database
GPG Key ID: 571C3A9C3B9E6FCA
10 changed files with 74 additions and 41 deletions

View File

@ -8,7 +8,7 @@ In a Git bash command prompt, `cd` to the directory where you intend to
install the source code.
```bash
git clone --recursive git@cpal.pw:~/wallet
git clone --recursive git@rho.la:~/wallet
```
Then launch the visual studio X64 native tools command prompt. `cd` to the

View File

@ -10,17 +10,25 @@ void ILogDebug(const char*);
void queue_error_message(const char*); //Used for error conditions within a destructor because you cannot throw within a destructor
void queue_fatal_error(const char*); //Used for fatal error conditions within a destructor in place of FatalException because you cannot throw within a destructor
struct sqlite3;
class MyException: public std::exception {
private:
std::string err;
int err_number;
public:
virtual ~MyException() override = default;
MyException() = delete;
explicit MyException(const std::string &m) noexcept :err(m){}
explicit MyException(const char* sz) noexcept :err(sz) {}
explicit MyException(const std::string &m) noexcept :err(m.c_str()),err_number(-1){}
explicit MyException(const char* sz) noexcept :err(sz),err_number(-1) {}
explicit MyException(const char* sz, int i) noexcept :err(sz), err_number(i) {}
explicit MyException(int, sqlite3*) noexcept;
virtual const char* what() const override {
return err.c_str();
}
virtual const int what_num() const {
return err_number;
}
};
class FatalException : public MyException {
@ -35,12 +43,6 @@ public:
HashReuseException() noexcept;
};
class SQLexception : public MyException {
public:
using MyException::MyException;
SQLexception() noexcept;
};
class NonUtf8DataInDatabase : public MyException {
public:
using MyException::MyException;

View File

@ -24,7 +24,7 @@ void sqlite3_init() {
if (sqlite3_initialize() != SQLITE_OK) {
errorCode = 7;
szError = "Fatal Error: Sqlite library did not init.";
// Cannot log the error, because logging not set up yet, so logging itself causes an exception
// Cannot log the error, because logging not set up yet, so logging itself causes an exception
throw FatalException(szError.c_str());
}
}
@ -35,7 +35,7 @@ static int callback(void* NotUsed, int argc, char** argv, char** azColName) {
std::string str;
str.reserve(256);
for (int i = 0; i < argc; i++) {
str =str + "\t\"" + azColName[i]+ R"|("=)|" + (argv[i]!=nullptr ? argv[i] : "NULL");
str = str + "\t\"" + azColName[i] + R"|("=)|" + (argv[i] != nullptr ? argv[i] : "NULL");
}
ILogMessage(str.c_str());
return 0;
@ -52,7 +52,7 @@ public:
pdb = nullptr;
#endif
int rc =sqlite3_open_v2(dbName, &pdb, flags, nullptr);
if (rc != SQLITE_OK) throw SQLexception(error_message(rc, pdb));
if (rc != SQLITE_OK) throw MyException(rc, pdb);
assert(pdb != nullptr);
// pdb can never be nullptr, since the sqlite3_open_v2 command always initializes
// it even if open fails
@ -62,7 +62,7 @@ public:
char* zErrMsg = nullptr;
int rc = sqlite3_exec(pdb, szsql, callback, nullptr, &zErrMsg);
if (rc != SQLITE_OK) {
SQLexception e(std::string("SQL Exec Error: ") + zErrMsg);
auto e = MyException(zErrMsg, rc);
sqlite3_free(zErrMsg);
throw e;
}
@ -90,6 +90,11 @@ ISqlite3* Sqlite3_open(const char * db_name) {
return new ISqlite3Impl(db_name, SQLITE_OPEN_READWRITE);
}
MyException::MyException(int i, sqlite3* pdb) noexcept:
err_number(i),
err(error_message(i, pdb))
{}
// Factory method to create database.
ISqlite3 * Sqlite3_create(const char* db_name) {
return new ISqlite3Impl(db_name, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
@ -101,10 +106,10 @@ class IcompiledImpl_sql :
friend class ISqlite3Impl;
private:
sqlite3_stmt *pStmt;
ISqlite3Impl *pdbImplOwn;
ISqlite3Impl*pdbImplOwn;
auto e(int rc) {
assert(rc != SQLITE_OK);
return SQLexception(error_message(rc, pdbImplOwn->pdb));
return MyException(rc, pdbImplOwn->pdb);
}
public:
IcompiledImpl_sql() = delete;
@ -192,7 +197,7 @@ public:
// from n blocks to n+1 blocks when a single transaction updates the root and anciliary data.
// We will build the blockchain hash table in postfix format, with patricia tree nodes that
// have skiplink format stored only in memory and rebuilt each startup so that it grows append only,
throw SQLexception("Abnormal busy database");
throw MyException("Abnormal busy database", 2^14+2);
break;
case SQLITE_MISUSE:
//ret = MISUSE;

View File

@ -114,8 +114,9 @@ namespace ro {
result step() {
return (*this)->Isqlite3_step();
}
void final_step() {
if (step() != result::DONE) throw SQLexception("SQL: Unexpected rows remaining");
if (step() != result::DONE) throw MyException("SQL: Unexpected rows remaining", 16384);
}
void reset() {
(*this)->Isqlite3_reset();
@ -183,12 +184,15 @@ class sql_insert_name {
ro::sql csql_into_names;
ro::sql csql_namekey_into_keys;
ro::sql csql_commit;
ro::sql csql_rollback;
public:
sql_insert_name(ISqlite3* p) :
csql_begin(p, R"|(BEGIN;)|"),
csql_into_names(p, R"|(INSERT OR ROLLBACK INTO "Names" VALUES(?1);)|"),
csql_namekey_into_keys(p, R"|(INSERT OR ROLLBACK INTO "Keys" VALUES(?1, last_insert_rowid(), 1);)|"),
csql_commit(p, R"|(COMMIT;)|") {}
csql_begin(p, R"|(BEGIN IMMEDIATE;)|"),
csql_into_names(p, R"|(INSERT OR FAIL INTO "Names" VALUES(?1);)|"),
csql_namekey_into_keys(p, R"|(INSERT OR FAIL INTO "Keys" VALUES(?1, last_insert_rowid(), 1);)|"),
csql_commit(p, R"|(COMMIT;)|"),
csql_rollback(p, R"|(ROLLBACK;)|")
{}
sql_insert_name(const std::unique_ptr<ISqlite3>& p) : sql_insert_name(p.get()) {}
void operator()(const char* psz, const ristretto255::point& pt) {
csql_begin.do_one();
@ -196,9 +200,18 @@ public:
csql_into_names.do_one(psz);
csql_namekey_into_keys.do_one(pt);
}
catch (const std::exception & e) {
csql_commit.do_one();
throw e;
catch (const MyException& e) {
csql_rollback.do_one();
if (e.what_num() == 19) {
throw MyException("Name already in database");
}
else {
throw;
}
}
catch (const std::exception &) {
csql_rollback.do_one();
throw;
}
csql_commit.do_one();
}

View File

@ -79,10 +79,10 @@ void display_wallet::close_menu_event_handler(wxCommandEvent& event) {
void display_wallet::add_name_event_handler(wxCommandEvent& event) {
wxTextEntryDialog dialog(this,
"This is a small sample\n"
"A long, long string to test out the text entrybox",
"Please enter a string",
"Default value",
R"("A Zooko name has a human readable name,
and a public key defined by the name and the wallet master secret)",
"Create a Zooko name",
"",
wxOK | wxCANCEL);
if (dialog.ShowModal() == wxID_OK)
{

View File

@ -65,7 +65,7 @@ Frame::Frame(wxString wxs)
m_panel(),
m_LastUsedSqlite()
{
try {
try {
assert(singletonFrame == nullptr);
singletonFrame = this;
SetIcon(wxICON(AAArho));
@ -150,14 +150,29 @@ try {
menuBar->EnableTop(1, false); //disable edit menu.
// child controls
m_LastUsedSqlite.Assign(singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")));
if (!m_LastUsedSqlite.IsOk() || !m_LastUsedSqlite.HasName() || !m_LastUsedSqlite.HasExt()) {
m_panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame. m_panel is a
// non owning pointer in the derived class that duplicates the owning pointer in the base class.
wxPanel* panel{ nullptr };
try {
if (m_LastUsedSqlite.IsOk())
{ //Try to load an existing file.
panel = new display_wallet(this, m_LastUsedSqlite);
}
else {
panel = new welcome_to_rhocoin(this);
}
}
else {
display_wallet* panel = new display_wallet(this, m_LastUsedSqlite);
m_panel = panel;
catch (const std::exception& e) {
// if the attempt to load an existing wallet file fails,
// we have to complete startup somehow.
queue_error_message(e.what());
panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame.
}
// m_panel is a non owning pointer in the derived class that duplicates the
// owning pointer in the base class. This looks like a violation of DIY.
// but I have the concept of the primary child of the frame window, while
// wxWidgets lacks that concept.
// m_panel signifies the child window of the frame that currently matters.
m_panel = panel;
this->RestorePositionFromConfig(ClientToWindowSize(m_panel->GetBestSize()));
SetClientSize(GetClientSize());
}
@ -230,7 +245,7 @@ void Frame::NewWallet(wxFileName& filename, ristretto255::hash<256>& secret) {
db->exec(R"|(
PRAGMA journal_mode = WAL;
PRAGMA synchronous = 1;
BEGIN TRANSACTION;
BEGIN IMMEDIATE TRANSACTION;
CREATE TABLE "Keys"(
"pubkey" BLOB NOT NULL UNIQUE PRIMARY KEY,
"id" integer NOT NULL,

View File

@ -129,8 +129,6 @@ FatalException::FatalException() noexcept :
MyException(R"|(unspecified fatal exception)|") {};
HashReuseException::HashReuseException() noexcept :
MyException(R"|(finalized the same hash constructor twice or more)|") {};
SQLexception::SQLexception() noexcept :
MyException(R"|(SQL Exception)|") {};
BadDataException::BadDataException() noexcept :
MyException(R"|(Bad data exception)|") {};
NonUtf8DataInDatabase::NonUtf8DataInDatabase() noexcept :

View File

@ -62,7 +62,7 @@ constexpr bool b_WINDOWS = false;
static_assert(wxUSE_UNSAFE_WXSTRING_CONV == 1,
R"(In fully utf environment, (wallet.manifest plus
/utf-8 compile option) all string conversions are safe.)");
static_assert(wxMAJOR_VERSION == 3 && wxMINOR_VERSION == 2 && wxRELEASE_NUMBER == 0 && wxSUBRELEASE_NUMBER == 1, "expecting wxWidgets 3.1.7");
static_assert(wxMAJOR_VERSION == 3 && wxMINOR_VERSION == 2 && wxRELEASE_NUMBER == 2 && wxSUBRELEASE_NUMBER == 1 && wxVERSION_STRING == wxT("wxWidgets 3.2.2.1"), "expecting wxWidgets 3.2.2.1");
static_assert(wxUSE_IPV6 == 1, "IP6 unavailable in wxWidgets");
static_assert(WXWIN_COMPATIBILITY_3_0 == 0, "wxWidgets api out of date");
static_assert(wxUSE_COMPILER_TLS == (b_WINDOWS ? 2 : 1), "out of date workarounds in wxWidgets for windows bugs");

View File

@ -424,7 +424,7 @@ static bool OpenWallet(void) {
db->exec(R"|(
PRAGMA journal_mode = WAL;
PRAGMA synchronous = 1;
BEGIN TRANSACTION;
BEGIN IMMEDIATE TRANSACTION;
CREATE TABLE "Keys"(
"pubkey" BLOB NOT NULL UNIQUE PRIMARY KEY,
"id" integer NOT NULL,

@ -1 +1 @@
Subproject commit 2648eb4da156a751a377cfe96b91faa03e535c10
Subproject commit 02e885c6f079c6e12a632f92cd7cfcceecf0c39b