From d50eaa6138904c7168561687593d102ac5fbce45 Mon Sep 17 00:00:00 2001 From: "reaction.la" Date: Tue, 19 Sep 2023 15:54:05 +1000 Subject: [PATCH] gave the root docs, README, LICENSE, and so forth, the new look --- docs/manifesto/mkdocs.sh | 7 +- docs/manifesto/scalability.md | 2 +- docs/rootDocs/README.md | 2 - docs/rootDocs/mkdocs.sh | 5 +- docs/rootDocs/navbar | 8 +- docs/writing_and_editing_documentation.md | 4 - msvc/make.bat | 32 +++++ msvc/wallet.vcxproj | 12 +- msvc/winConfig.bat | 12 +- msvc/winConfigDebug.bat | 91 ++++++++++++++ msvc/winConfigRelease.bat | 100 ++++++++++++++++ msvc/wxConfig.bat | 49 ++++++++ src/ILog.cpp | 9 ++ src/ILog.h | 2 + src/db_accessors.h | 15 ++- src/display_wallet.cpp | 11 +- src/frame.cpp | 14 ++- src/introspection_of_standard_C_types.h | 5 + src/stdafx.h | 8 +- src/unit_test.cpp | 139 +++++++++++++++------- 20 files changed, 445 insertions(+), 82 deletions(-) create mode 100644 msvc/make.bat create mode 100644 msvc/winConfigDebug.bat create mode 100644 msvc/winConfigRelease.bat create mode 100644 msvc/wxConfig.bat diff --git a/docs/manifesto/mkdocs.sh b/docs/manifesto/mkdocs.sh index 145e0ee..2cfb4a5 100644 --- a/docs/manifesto/mkdocs.sh +++ b/docs/manifesto/mkdocs.sh @@ -3,7 +3,6 @@ set -e cd `dirname $0` docroot="../" banner_height=banner_height:15ex -templates=$docroot"pandoc_templates" if [[ "$OSTYPE" == "linux-gnu"* ]]; then osoptions="" elif [[ "$OSTYPE" == "darwin"* ]]; then @@ -13,10 +12,10 @@ elif [[ "$OSTYPE" == "cygwin" ]]; then elif [[ "$OSTYPE" == "msys" ]]; then osoptions="--fail-if-warnings --eol=lf " fi -options=$osoptions"--toc --number-sections --toc-depth=5 --from markdown+smart+raw_html+fenced_divs+bracketed_spans --to html5 --wrap=preserve --metadata=lang:en --css=$templates/style.css -Bnavbar -o" if [[ -z $targetDocroot ]]; then targetDocroot=$docroot fi +options=$osoptions"--toc --number-sections --toc-depth=5 --from markdown+smart+raw_html+fenced_divs+bracketed_spans --to html5 --wrap=preserve --metadata=lang:en --css=$targetDocroot"pandoc_templates/style.css" -Bnavbar -o" for f in * do [[ -d $item && -x $item/mkdocs.sh ]] && $item/mkdocs.sh @@ -33,10 +32,10 @@ do katex=" --katex="$docroot fi done <$f - pandoc --variable $banner_height --variable targetDocroot:$targetDocroot --template $templates/pandoc.template $katex $options $destdir$base.html $base.md + pandoc --variable $banner_height --variable targetDocroot:$targetDocroot --template $docroot"pandoc_templates/pandoc.template" $katex $options $destdir$base.html $base.md echo "$destdir$base.html from $f" #else # echo " $base.html up to date" fi fi -done +done \ No newline at end of file diff --git a/docs/manifesto/scalability.md b/docs/manifesto/scalability.md index 54d764d..ccaffeb 100644 --- a/docs/manifesto/scalability.md +++ b/docs/manifesto/scalability.md @@ -70,7 +70,7 @@ A struct is simply some binary data laid out in well known and agreed format. Almost the same thing as an sql row, except that an sql row does not have a well known and agreed binary format, so does not have a well defined hash, and a struct is not -necessarily part of an sql table, though obvious you can put a +necessarily part of an sql table, though obviously you can put a bunch of structs of the same type in an sql table, and represent an sql table as a bunch of structs, plus at least one primary index. An sql table is equivalent to a pile of structs, diff --git a/docs/rootDocs/README.md b/docs/rootDocs/README.md index 5133f3f..ee258a0 100644 --- a/docs/rootDocs/README.md +++ b/docs/rootDocs/README.md @@ -1,8 +1,6 @@ --- title: >- README -sidebar: true -notmine: false --- [pre alpha documentation (mostly a wish list)](docs/index.htm) diff --git a/docs/rootDocs/mkdocs.sh b/docs/rootDocs/mkdocs.sh index dc0d901..8f098f2 100644 --- a/docs/rootDocs/mkdocs.sh +++ b/docs/rootDocs/mkdocs.sh @@ -5,7 +5,6 @@ docroot="../" targetDocroot="docs/" destdir="../../" banner_height=banner_height:15ex -templates=$docroot"pandoc_templates" if [[ "$OSTYPE" == "linux-gnu"* ]]; then osoptions="" elif [[ "$OSTYPE" == "darwin"* ]]; then @@ -15,10 +14,10 @@ elif [[ "$OSTYPE" == "cygwin" ]]; then elif [[ "$OSTYPE" == "msys" ]]; then osoptions="--fail-if-warnings --eol=lf " fi -options=$osoptions"--toc --number-sections --toc-depth=5 --from markdown+smart+raw_html+fenced_divs+bracketed_spans --to html5 --wrap=preserve --metadata=lang:en --css=$templates/style.css -Bnavbar -o" if [[ -z $targetDocroot ]]; then targetDocroot=$docroot fi +options=$osoptions"--toc --number-sections --toc-depth=5 --from markdown+smart+raw_html+fenced_divs+bracketed_spans --to html5 --wrap=preserve --metadata=lang:en --css=$targetDocroot/pandoc_templates/style.css -Bnavbar -o" for f in * do [[ -d $item && -x $item/mkdocs.sh ]] && $item/mkdocs.sh @@ -35,7 +34,7 @@ do katex=" --katex="$docroot fi done <$f - pandoc --variable $banner_height --variable targetDocroot:$targetDocroot --template $templates/pandoc.template $katex $options $destdir$base.html $base.md + pandoc --variable $banner_height --variable targetDocroot:$targetDocroot --template $docroot"pandoc_templates/pandoc.template" $katex $options $destdir$base.html $base.md echo "$destdir$base.html from $f" #else # echo " $base.html up to date" diff --git a/docs/rootDocs/navbar b/docs/rootDocs/navbar index a10f78c..924817b 100644 --- a/docs/rootDocs/navbar +++ b/docs/rootDocs/navbar @@ -1,7 +1,7 @@
- vision - scalability - social networking - revelation + readme + license + notice + release notes
\ No newline at end of file diff --git a/docs/writing_and_editing_documentation.md b/docs/writing_and_editing_documentation.md index 83ee80c..cd5ffca 100644 --- a/docs/writing_and_editing_documentation.md +++ b/docs/writing_and_editing_documentation.md @@ -183,10 +183,6 @@ compile correctly, but `\ln` and `\log` is more likely to compile correctly than symbol. $$\ln(1+x)=x-\bigcirc(x^2)$$ $$H(a|b|v)$$ -$\begin{align} - a&=b+c \\ - d+e&=f -\end{align}$ though it is subtly prettier with katex, and some maths expressions will break Pandoc unless one tells it to use katex. diff --git a/msvc/make.bat b/msvc/make.bat new file mode 100644 index 0000000..7678c9e --- /dev/null +++ b/msvc/make.bat @@ -0,0 +1,32 @@ +echo on +call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat +call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +echo on +msbuild wallet.sln -p:Configuration=Debug;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +msbuild wallet.sln -p:Configuration=Release;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +.\build\Debug\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on debug build +) ELSE ( + echo passed unit test on debug build) +echo on +.\build\Release\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on release build +) ELSE ( + echo passed unit test on release build +) diff --git a/msvc/wallet.vcxproj b/msvc/wallet.vcxproj index 49c8256..e9799ea 100644 --- a/msvc/wallet.vcxproj +++ b/msvc/wallet.vcxproj @@ -44,7 +44,7 @@ true $(SolutionDir)wxWidgets\include\msvc;$(SolutionDir)wxWidgets\include;$(SolutionDir)libsodium\src\libsodium\include;$(SolutionDir)mpir;$(IncludePath) - $(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\Build\Debug\X64;$(SolutionDir)mpir\lib\x64\Debug;$(LibraryPath) + $(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\bin\x64\Debug\v143\static;$(SolutionDir)mpir\lib\x64\Debug;$(LibraryPath) $(SolutionDir)build\$(Configuration)\ $(SolutionDir)build\$(Configuration)\ @@ -52,7 +52,7 @@ false $(SolutionDir)wxWidgets\include\msvc;$(SolutionDir)wxWidgets\include;$(SolutionDir)libsodium\src\libsodium\include;$(SolutionDir)mpir;$(IncludePath) - $(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\Build\Release\X64;$(SolutionDir)mpir\lib\x64\Release;$(LibraryPath) + $(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\bin\x64\Release\v143\static;$(SolutionDir)mpir\lib\x64\Release;$(LibraryPath) $(SolutionDir)build\$(Configuration)\ $(SolutionDir)build\$(Configuration)\ @@ -75,9 +75,8 @@ Windows true - - - mpir.lib;mpirxx.lib;%(AdditionalDependencies) + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib + mpir.lib;mpirxx.lib;libsodium.lib;%(AdditionalDependencies) wallet.manifest %(AdditionalManifestFiles) @@ -115,7 +114,8 @@ true true true - mpir.lib;mpirxx.lib;%(AdditionalDependencies) + mpir.lib;mpirxx.lib;libsodium.lib;%(AdditionalDependencies) + /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib %(AdditionalOptions) diff --git a/msvc/winConfig.bat b/msvc/winConfig.bat index f07f430..d5de85e 100644 --- a/msvc/winConfig.bat +++ b/msvc/winConfig.bat @@ -2,8 +2,8 @@ echo on call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" echo on -cd libsodium -msbuild libsodium.vcxproj -p:Configuration=Release;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 -m +cd libsodium/builds/msvc/vs2022 +msbuild libsodium.sln -p:Configuration=StaticRelease;Platform=x64 -m echo off IF %ERRORLEVEL% NEQ 0 ( cd .. @@ -11,7 +11,7 @@ IF %ERRORLEVEL% NEQ 0 ( GOTO:EOF ) echo on -msbuild libsodium.vcxproj -p:Configuration=Debug;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 -m +msbuild libsodium.sln -p:Configuration=StaticDebug;Platform=x64 -m echo off IF %ERRORLEVEL% NEQ 0 ( cd .. @@ -19,7 +19,8 @@ IF %ERRORLEVEL% NEQ 0 ( GOTO:EOF ) echo on -cd ..\mpir\msvc\vs22 +cd ../../../.. +cd mpir\msvc\vs22 call msbuild.bat gc lib x64 Debug echo off IF %ERRORLEVEL% NEQ 0 ( @@ -113,7 +114,8 @@ echo off IF %ERRORLEVEL% NEQ 0 ( echo failed unit test on debug build ) ELSE ( - echo passed unit test on debug build) + echo passed unit test on debug build +) echo on .\build\Release\wallet.exe --complete --test echo off diff --git a/msvc/winConfigDebug.bat b/msvc/winConfigDebug.bat new file mode 100644 index 0000000..85bb725 --- /dev/null +++ b/msvc/winConfigDebug.bat @@ -0,0 +1,91 @@ +echo as it is a bitch to make sure you are linking to the correct libraries, this batch Files +echo exists to make sure no other libraries are around +echo off +call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat +call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +del /Q build +del /Q libsodium\obj +del /Q libsodium\bin +del /Q libsodium\src\libsodium\include\sodium\version.h +cd mpir +del config.h +del gmp-mparam.h +del gmp.h +del /Q lib +del longlong.h +del mpir.h +del msvc\output_params.bat +del msvc\tmp.h +del /Q msvc\vs22\lib_mpir_cxx\x64 +del /Q msvc\vs22\lib_mpir_gc\x64 +del msvc\vs22\test-config.props +cd ..\wxWidgets +del /Q build\msw\vc_x64_mswu +del /Q build\msw\vc_x64_mswud +del /Q lib\vc_x64_lib +cd .. +echo check to see that everything is cleaned +echo off +git submodule foreach --recursive "git clean -xnf" +git clean -xnf +PAUSE +echo on + +cd libsodium/builds/msvc/vs2022 +msbuild libsodium.sln -p:Configuration=StaticDebug;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +echo on +cd ../../../.. +cd mpir\msvc\vs22 +call msbuild.bat gc lib x64 Debug +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +call msbuild.bat gc lib x64 Debug test +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +call msbuild.bat gc lib x64 Debug tune +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on + +echo on +cd ..\..\.. +cd wxWidgets\build\msw +echo on +msbuild wx_vc17.sln -m -p:Configuration=Debug;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) + + +cd ..\..\.. +msbuild wallet.sln -p:Configuration=Debug;Platform=x64 -m +.\build\Debug\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on debug build +) ELSE ( + echo passed unit test on debug build +) diff --git a/msvc/winConfigRelease.bat b/msvc/winConfigRelease.bat new file mode 100644 index 0000000..eb2396a --- /dev/null +++ b/msvc/winConfigRelease.bat @@ -0,0 +1,100 @@ +echo as it is a bitch to make sure you are linking to the correct libraries, this batch Files +echo exists to make sure no other libraries are around +echo off +call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat +call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +del /Q build +del /Q libsodium\obj +del /Q libsodium\bin +del /Q libsodium\src\libsodium\include\sodium\version.h +cd mpir +del config.h +del gmp-mparam.h +del gmp.h +del /Q lib +del longlong.h +del mpir.h +del msvc\output_params.bat +del msvc\tmp.h +del /Q msvc\vs22\lib_mpir_cxx\x64 +del /Q msvc\vs22\lib_mpir_gc\x64 +del msvc\vs22\test-config.props +cd ..\wxWidgets +del /Q build\msw\vc_x64_mswu +del /Q build\msw\vc_x64_mswud +del /Q lib\vc_x64_lib +cd .. +echo check to see that everything is cleaned +echo off +git submodule foreach --recursive "git clean -xnf" +git clean -xnf +PAUSE +echo on +cd libsodium/builds/msvc/vs2022 +msbuild libsodium.sln -p:Configuration=StaticRelease;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +cd ../../../.. +cd mpir\msvc\vs22 +echo on +call msbuild.bat gc lib x64 Release +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +call msbuild.bat gc lib x64 Release test +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +call msbuild.bat gc lib x64 Release tune +echo off +IF %ERRORLEVEL% NEQ 0 ( + cd .. + PAUSE + GOTO:EOF +) +echo on +cd ..\..\.. +cd wxWidgets\build\msw +msbuild wx_vc17.sln -m -p:Configuration=Release;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +msbuild wx_vc17.sln -m -p:Configuration=Debug;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) + +echo on +cd ..\..\.. +msbuild wallet.sln -p:Configuration=Release;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +.\build\Release\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on release build +) ELSE ( + echo passed unit test on release build +) diff --git a/msvc/wxConfig.bat b/msvc/wxConfig.bat new file mode 100644 index 0000000..5d705d4 --- /dev/null +++ b/msvc/wxConfig.bat @@ -0,0 +1,49 @@ +echo on +call C:\"Program Files (x86)"\"Microsoft Visual Studio"\2022\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat +call C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" +echo on +cd wxWidgets\build\msw +msbuild wx_vc17.sln -m -p:Configuration=Release;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +msbuild wx_vc17.sln -m -p:Configuration=Debug;Platform=x64;PlatformToolset=v143;WindowsTargetPlatformVersion=10.0 +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) + +echo on +cd ..\..\.. +msbuild wallet.sln -p:Configuration=Debug;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +msbuild wallet.sln -p:Configuration=Release;Platform=x64 -m +echo off +IF %ERRORLEVEL% NEQ 0 ( + PAUSE + GOTO:EOF +) +echo on +.\build\Debug\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on debug build +) ELSE ( + echo passed unit test on debug build) +echo on +.\build\Release\wallet.exe --complete --test +echo off +IF %ERRORLEVEL% NEQ 0 ( + echo failed unit test on release build +) ELSE ( + echo passed unit test on release build +) diff --git a/src/ILog.cpp b/src/ILog.cpp index 42c492f..1fa6f2c 100644 --- a/src/ILog.cpp +++ b/src/ILog.cpp @@ -38,3 +38,12 @@ void queue_fatal_error(const char* psz) { queue_error_message(psz); singletonFrame->Close(); } + +MyException::MyException(const char* sz, int i, const char* func__, const char* FILE__) noexcept : +// usage +// throw MyException("Expected wallet file not found", __LINE__, __func__, __FILE__); + err_number(i) { + char buff[20]; + snprintf(buff, 20, "%d", i); + err = std::string(sz) + "\nline " + buff + ", function " + func__ + ", file " + FILE__; +} diff --git a/src/ILog.h b/src/ILog.h index bee8b24..68f11ca 100644 --- a/src/ILog.h +++ b/src/ILog.h @@ -22,6 +22,8 @@ public: 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(const char* sz, int i, const char*, const char*) noexcept; + // usage throw MyException("error", __LINE__, __func__, __FILE__); explicit MyException(int, sqlite3*) noexcept; virtual const char* what() const override { return err.c_str(); diff --git a/src/db_accessors.h b/src/db_accessors.h index 72c037c..e68d6c0 100644 --- a/src/db_accessors.h +++ b/src/db_accessors.h @@ -166,7 +166,7 @@ public: class sql_read_from_misc :ro::sql { public: - sql_read_from_misc(ISqlite3 *p) : sql(p, R"|(SELECT "m" FROM "Misc" WHERE "index" = ?1;)|") {} + sql_read_from_misc(ISqlite3 *p) : sql(p, R"|(SELECT "m" FROM "Misc" WHERE "ROWID" = ?1;)|") {} sql_read_from_misc(const std::unique_ptr& p) : sql_read_from_misc(p.get()){} auto operator()(int i) { return read_one(i); @@ -188,8 +188,13 @@ class sql_insert_name { public: sql_insert_name(ISqlite3* p) : 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_into_names(p, R"|(INSERT OR FAIL INTO "Names" VALUES(NULL, ?1);)|"), + csql_namekey_into_keys(p, R"|(INSERT OR FAIL INTO "Keys" VALUES(NULL, ?1, last_insert_rowid(), 1);)|"), + /* NULL triggers special nonstandard Sqlite behavior to autogenerate a unique ROWID + Because we explicitly make the ROWID a named field in the table to avoid too much + non standard SQlite behavior, we must explicitly provide a placeholder in the INSERT + statement. So at least we only get special SQlite3 behavior when we deliberately + invoke it. */ csql_commit(p, R"|(COMMIT;)|"), csql_rollback(p, R"|(ROLLBACK;)|") {} @@ -219,13 +224,13 @@ public: class sql_read_name :ro::sql { public: - sql_read_name(ISqlite3* p) : sql(p, R"|(SELECT * FROM "Names" WHERE OID = ?1;)|") {} + sql_read_name(ISqlite3* p) : sql(p, R"|(SELECT * FROM "Names" WHERE ROWID = ?1;)|") {} sql_read_name(const std::unique_ptr& p) : sql_read_name(p.get()) {} bool operator()(int i) { return read_one(i) == Icompiled_sql::ROW; } auto name() const { - return sql::column(0); + return sql::column(1); } }; diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 9430788..11a6efa 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -24,11 +24,14 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : SetSizer(sizer); ro::sql read_keys(m_db, R"|(SELECT * FROM "Keys";)|"); sql_read_name read_name(m_db); //*It would be better to have a select statement goes through the name table, in name order. This is unit test code wrongly repurposed. + /* ro::sql sql_read_names( + m_db, + R"|(SELECT Names.name, Keys.pubkey FROM Names INNER JOIN Keys ON Names.ROWID=Keys.id AND Keys.use=1 ORDER BY Names.name;)|"){} */ // m_db.reset(nullptr);// Force error of premature destruction of Isqlite3 while (read_keys.step() == Icompiled_sql::ROW) { - auto pubkey = read_keys.column(0); - auto id = read_keys.column(1); - auto use = read_keys.column(2); + auto pubkey = read_keys.column(1); + auto id = read_keys.column(2); + auto use = read_keys.column(3); if (use != 1)throw MyException(sz_unknown_secret_key_algorithm); if (!read_name(id)) throw MyException(sz_no_corresponding_entry); const char* name = read_name.name(); @@ -106,4 +109,4 @@ void display_wallet::OnClose(wxCloseEvent& event) { // replacing the default handler.' if (singletonFrame->m_panel ==this)singletonFrame->m_panel = nullptr; -} \ No newline at end of file +} diff --git a/src/frame.cpp b/src/frame.cpp index 7483213..6708f5c 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -242,21 +242,31 @@ void Frame::NewWallet(wxFileName& filename, ristretto255::hash<256>& secret) { // Disk operations to create wallet, which may throw. // This try/catch block exists to catch disk io issues. db.reset(Sqlite3_create(filename.GetFullPath().ToUTF8())); + // To avoid legacy quirks and backward bug compatibility, every sqlite3 table needs an INTEGER PRIMARY KEY or a WITHOUT ROWID. + // if you want a non integer primary key and do not want to use sqlite3's complicated backward bug compatibility special feature, + // instead use a CREATE INDEX rather than making the thing a primary key. db->exec(R"|( PRAGMA journal_mode = WAL; PRAGMA synchronous = 1; BEGIN IMMEDIATE TRANSACTION; CREATE TABLE "Keys"( - "pubkey" BLOB NOT NULL UNIQUE PRIMARY KEY, + "ROWID" INTEGER PRIMARY KEY, + "pubkey" BLOB NOT NULL UNIQUE, "id" integer NOT NULL, "use" INTEGER NOT NULL); +CREATE UNIQUE INDEX i_pubkey ON Keys (pubkey); +CREATE UNIQUE INDEX i_id ON Keys (use, id); + CREATE TABLE "Names"( + "ROWID" INTEGER PRIMARY KEY, "name" TEXT NOT NULL UNIQUE ); +CREATE UNIQUE INDEX i_names ON Names (name); + CREATE TABLE "Misc"( - "index" INTEGER NOT NULL UNIQUE PRIMARY KEY, + "ROWID" INTEGER PRIMARY KEY, "m" BLOB ); COMMIT;)|"); diff --git a/src/introspection_of_standard_C_types.h b/src/introspection_of_standard_C_types.h index a0146f2..b9c30e6 100644 --- a/src/introspection_of_standard_C_types.h +++ b/src/introspection_of_standard_C_types.h @@ -169,3 +169,8 @@ std::enable_if_t, decltype(std::span(declval())[0] } return retval; } +#pragma warning(disable : 5056) +// This header file turns off deprecation of array type compares, because +// it provides an array spaceship operator that solves the inconsistency +// problem in a better way. Spaceship compares of arrays in my code are +// no longer ill formed. \ No newline at end of file diff --git a/src/stdafx.h b/src/stdafx.h index b578fed..a48208b 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -62,7 +62,6 @@ 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 == 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"); @@ -72,6 +71,7 @@ static_assert(wxUSE_STD_CONTAINERS == 1, "wxWidgets api out of date"); static_assert(wxUSE_STD_STRING_CONV_IN_WXSTRING == 1, "want wxString to conform to std::string"); static_assert(wxUSE_SECRETSTORE >0, "need wxSecretStore to actually work"); // The api may be there, but will always return false if wxUSE_SECRETSTORE is zero +static_assert(wxUSE_STD_DEFAULT == 1 && wxUSE_STL==1); std::span& operator^=(std::span&, byte *); #ifndef wxHAS_IMAGES_IN_RESOURCES #include "rho.xpm" //Defines the icon AAArho on linux @@ -82,9 +82,13 @@ std::span& operator^=(std::span&, byte *); #define SODIUM_STATIC 1 #include #include -#pragma comment(lib, "libsodium.lib") inline wxString _wx(const char* sz) { return wxString::FromUTF8Unchecked(sz); } #include "introspection_of_standard_C_types.h" +// This header file turns off deprecation of array type compares, because +// it provides an array spaceship operator that solves the inconsistency +// problem in a better way. Spaceship compares of arrays in my code are +// no longer ill formed. +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"); #include "rotime.h" #include "slash6.h" #include "ISqlite3.h" diff --git a/src/unit_test.cpp b/src/unit_test.cpp index 40f6faa..9ce7780 100644 --- a/src/unit_test.cpp +++ b/src/unit_test.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +static constexpr char SrcFilename[]{ "src/unit_test.cpp" }; using ro::msec, ro::msec_since_epoch, ro::bin2hex, ro::to_base64_string, ristretto255::hash, ristretto255::hsh, ristretto255::scalar, ristretto255::point, ro::base58; @@ -68,6 +69,11 @@ static bool EndUnitTest() { throw EndUnitTestOfExceptions(); } catch (const EndUnitTestOfExceptions&) {} + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception& e) { errorCode = 1001; szError = intestbed + e.what(); @@ -105,7 +111,7 @@ static bool curve_order(void) { mpz_get_str(sz, 16, mpir::ristretto25519_curve_order); wxString curve_order_as_mpir_bigint{ _wx(sz) }; if (curve_order_as_unreduced_scalar != curve_order_as_mpir_bigint){ - throw MyException("inconsistent curve order"); + throw MyException("inconsistent curve order", __LINE__, __func__, SrcFilename); } scalar sc_zero{ 0 }; scalar sc_one{ 1 }; @@ -138,7 +144,12 @@ static bool curve_order(void) { && sc1.valid()) && !scalar::scOrder.valid() && !scalar(0).valid(); - if (!f)throw MyException("scalar range and validation messed up"); + if (!f)throw MyException("scalar range and validation messed up", __LINE__, __func__, SrcFilename); + } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); } catch (const std::exception& e) { errorCode = 30; @@ -180,14 +191,14 @@ static bool checkDataConversionsProduceExpected(void){ || hash(p_brownfox) != hash(hsh() << ar_brownfox << wx_over.ToUTF8()) || hash(p_brownfox) != hash(ar_brownfox, wx_over.ToUTF8()) || hash(brownfox) != hash(ar_brownfox, p_over) - )throw MyException(sz_inconsistent_hash); + )throw MyException(sz_inconsistent_hash, __LINE__, __func__, SrcFilename); { scalar scl_b{ scalar::random() }; point pt_a{ scl_b.timesBase() }; std::string str_pt_a{ &(base58(pt_a))[0] }; if (pt_a != base58::bin(str_pt_a.c_str())){ - MyException("Round trip from and two base 58 representation failed"); + throw MyException("Round trip from and two base 58 representation failed", __LINE__, __func__, SrcFilename); } } { @@ -231,9 +242,14 @@ static bool checkDataConversionsProduceExpected(void){ if (base58(hash_b).operator std::string() != "i22EVNPsKRjdxYTZrPPu9mx6vnrBjosFix5F4gn2mb2kF" ){ - throw MyException("unexpected hash of transformations"); + throw MyException("unexpected hash of transformations", __LINE__, __func__, SrcFilename); } } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception& e) { errorCode = 27; szError = e.what(); @@ -277,6 +293,11 @@ static bool CheckForUtfEnvironment(void) { } if (!utfEnvironment) { throw MyException(utfError); } } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception& e) { errorCode = 24; szError = e.what(); @@ -386,28 +407,24 @@ static bool OpenWallet(void) { else fWalletNameOk = true; std::unique_ptr db; if (fWalletNameOk) { - if (!LastUsedSqlite.FileExists()) throw MyException("Expected wallet file not found"); + if (!LastUsedSqlite.FileExists()) throw MyException("Expected wallet file not found", __LINE__, __func__, SrcFilename); db.reset(Sqlite3_open(LastUsedSqlite.GetFullPath().ToUTF8())); sql_read_from_misc read_from_misc(db.get()); - if(!read_from_misc(1) || read_from_misc.value() != WALLET_FILE_IDENTIFIER)throw MyException("Unrecognizable wallet file format"); - if(!read_from_misc(2) || read_from_misc.value() != WALLET_FILE_SCHEMA_VERSION_0_0)throw MyException("Unrecognized wallet schema"); - if (!read_from_misc(4)) throw MyException("Mastersecret missing"); + if(!read_from_misc(1) || read_from_misc.value() != WALLET_FILE_IDENTIFIER)throw MyException("Unrecognizable wallet file format", __LINE__, __func__, SrcFilename); + if(!read_from_misc(2) || read_from_misc.value() != WALLET_FILE_SCHEMA_VERSION_0_0)throw MyException("Unrecognized wallet schema", __LINE__, __func__, SrcFilename); + if (!read_from_misc(4)) throw MyException("Mastersecret missing", __LINE__, __func__, SrcFilename); ristretto255::CMasterSecret MasterSecret(*read_from_misc.value()); ro::sql read_keys(db.get(), R"|(SELECT * FROM "Keys" LIMIT 5;)|"); sql_read_name read_name(db.get()); // db.reset(nullptr);// Force error of premature destruction of Isqlite3 while (read_keys.step() == Icompiled_sql::ROW) { - auto pubkey = read_keys.column(0); - auto id = read_keys.column(1); - auto use = read_keys.column(2); - if (use != 1){ - throw MyException(R"|(Unknown secret key algorithm index in "Names" table)|"); - } - if (!read_name(id)){ - throw MyException(R"|(No entry corresponding to public key in "Names" table)|"); - } + auto pubkey = read_keys.column(1); + auto id = read_keys.column(2); + auto use = read_keys.column(3); + if (use != 1)throw MyException(sz_unknown_secret_key_algorithm, __LINE__, __func__, SrcFilename); + if (!read_name(id)) throw MyException(sz_no_corresponding_entry, __LINE__, __func__, SrcFilename); const char* name = read_name.name(); - if(MasterSecret(name).timesBase()!=*pubkey)throw MyException(R"|(Public key of name fails to correspond)|"); + if(MasterSecret(name).timesBase()!=*pubkey)throw MyException(R"|(Public key of name fails to correspond)|", __LINE__, __func__, SrcFilename); wxLogMessage(wxT("\t\t\"%s\" has expected public key 0x%s"), name, (wxString)(bin2hex(*pubkey))); } } @@ -426,16 +443,23 @@ PRAGMA journal_mode = WAL; PRAGMA synchronous = 1; BEGIN IMMEDIATE TRANSACTION; CREATE TABLE "Keys"( - "pubkey" BLOB NOT NULL UNIQUE PRIMARY KEY, + "ROWID" INTEGER PRIMARY KEY, + "pubkey" BLOB NOT NULL UNIQUE, "id" integer NOT NULL, "use" INTEGER NOT NULL); +CREATE UNIQUE INDEX i_pubkey ON Keys (pubkey); +CREATE UNIQUE INDEX i_id ON Keys (use, id); + CREATE TABLE "Names"( + "ROWID" INTEGER PRIMARY KEY, "name" TEXT NOT NULL UNIQUE ); +CREATE UNIQUE INDEX i_names ON Names (name); + CREATE TABLE "Misc"( - "index" INTEGER NOT NULL UNIQUE PRIMARY KEY, + "ROWID" INTEGER PRIMARY KEY, "m" BLOB ); COMMIT;)|"); @@ -468,6 +492,11 @@ COMMIT;)|"); } } // End of wallet creation branch } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception & e) { errorCode = 20; szError = e.what(); @@ -514,11 +543,11 @@ namespace ristretto255 { szError = "Fail\tUnexpected text secret from scalar(7)"; ILogError(szError.c_str()); } - if (std::popcount(0x0123456789ABCDEFu) != 0x20)throw MyException(sz_bitcount_incorrect); - if (rounded_log2(0x345678u) != 22) throw MyException(sz_rounded_log2_incorrect); + if (std::popcount(0x0123456789ABCDEFu) != 0x20)throw MyException(sz_bitcount_incorrect, __LINE__, __func__, SrcFilename); + if (rounded_log2(0x345678u) != 22) throw MyException(sz_rounded_log2_incorrect, __LINE__, __func__, SrcFilename); { uint64_t v{ 0x123456789ABCDEFu }; for (unsigned int i = 0; i <= 64; i++) { - if (i != std::countr_zero(v))throw MyException(sz_count_of_trailing_zero_bits_incorrect); + if (i != std::countr_zero(v))throw MyException(sz_count_of_trailing_zero_bits_incorrect, __LINE__, __func__, SrcFilename); v <<= 1; } } @@ -554,6 +583,11 @@ namespace ristretto255 { ILogMessage("\t\tSkipping test of strong secret generation in quick unit test, because strong secret generation is deliberately slow."); } } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception & e) { errorCode = 16; szError = e.what(); @@ -571,7 +605,7 @@ namespace ristretto255 { static bool TestShareSecretGenerationSpeed(void) { ILogMessage("\tTest shared secret generation speed."); try { - // throw MyException("fake failure to test failure handling"); + // throw MyException("fake failure to test failure handling", __LINE__, __func__, SrcFilename); unsigned int secrets{ 10 }; scalar a{ scalar::random() }; scalar b{ scalar::random() }; @@ -588,7 +622,8 @@ static bool TestShareSecretGenerationSpeed(void) { B = b * A; } auto end_time{ std::chrono::high_resolution_clock::now() }; - if (!B.valid()) { throw MyException("Unexpected invalid scalar"); } + if (!B.valid()) { throw MyException("Unexpected invalid scalar", __LINE__, __func__, SrcFilename); + } auto time_taken{ std::chrono::duration_cast (end_time - start_time) }; wxLogMessage("\t\t%d shared secrets from public and private keys took %lld microseconds", secrets * 3, time_taken.count()); if (time_taken.count()) { @@ -598,6 +633,11 @@ static bool TestShareSecretGenerationSpeed(void) { ); } } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception& e) { errorCode = 23; szError = e.what(); @@ -736,6 +776,11 @@ static bool TestShareSecretGenerationSpeed(void) { wxLogMessage(wxT("\t\tcrypto_shorthash_KEYBYTES\t== %08x"), crypto_shorthash_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_auth_BYTES\t\t== %08x"), crypto_auth_BYTES); } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception & e) { errorCode = 15; szError = e.what(); @@ -788,9 +833,9 @@ static bool TestShareSecretGenerationSpeed(void) { auto start_time{ std::chrono::high_resolution_clock::now() }; auto sclr_a = scalar::random(); auto sclr_b = scalar::random(); - if (sclr_a == sclr_b)throw MyException("random not very random"); + if (sclr_a == sclr_b)throw MyException("random not very random", __LINE__, __func__, SrcFilename); auto sclr_c = sclr_a * sclr_b; - if (sclr_b != sclr_c / sclr_a)throw MyException("multiplicative inverse not inverse"); + if (sclr_b != sclr_c / sclr_a)throw MyException("multiplicative inverse not inverse", __LINE__, __func__, SrcFilename); if (false || !scalar::random().valid() || point::ptBase - point::ptBase != point::ptZero @@ -892,13 +937,13 @@ static bool TestShareSecretGenerationSpeed(void) { hash( hsh() << first << second ) - ) throw MyException("inconsistent hashes generated on strings"); + ) throw MyException("inconsistent hashes generated on strings", __LINE__, __func__, SrcFilename); const char* _ = "hello"; hash a(_); hash b(a); hash c(b); if (hash(b, c) != hash(hsh() << b << c) - ) throw MyException("inconsistent hashes generated"); + ) throw MyException("inconsistent hashes generated", __LINE__, __func__, SrcFilename); constexpr int hashes{ 3000 }; start_time = std::chrono::high_resolution_clock::now(); for (int i{ 0 }; i < hashes; i++) { @@ -917,20 +962,29 @@ static bool TestShareSecretGenerationSpeed(void) { } } } - uint8_t buff[hashes * 3 * 64]; - randombytes_buf(std::span(buff)); - start_time = std::chrono::high_resolution_clock::now(); - c = hash(buff); - end_time = std::chrono::high_resolution_clock::now(); - time_taken = std::chrono::duration_cast (end_time - start_time); - { bool f = false; //dont optimize pointless calculation away - for (auto x : c.blob) { f = f || x; } - if (f) { - wxLogMessage(_wx("\t\tone hash of %d bytes took %lld microseconds"), hashes * 3 * 64, time_taken.count()); + { + std::unique_ptr uBuff = std::make_unique(hashes * 3 * 64); + auto sBuff = std::span(uBuff.get(), hashes * 3 * 64); + randombytes_buf(sBuff); + start_time = std::chrono::high_resolution_clock::now(); + c = hash(sBuff); + end_time = std::chrono::high_resolution_clock::now(); + time_taken = std::chrono::duration_cast (end_time - start_time); + { bool f = false; //dont optimize pointless calculation away + for (auto x : c.blob) { f = f || x; } + if (f) { + wxLogMessage(_wx("\t\tone hash of %d bytes took %lld microseconds"), hashes * 3 * 64, time_taken.count()); + } } } + } } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception & e) { errorCode = 10; szError = e.what(); @@ -1077,6 +1131,11 @@ static bool slash6UnitTest(void) { } // If you touch the slash6 encoding, try retesting with the number of tests tries set to one hundred thousand instead of five, to catch all code paths and weird special cases. } + catch (const MyException& e) { + errorCode = e.what_num(); + szError = e.what(); + ILogError(szError.c_str()); + } catch (const std::exception & e) { errorCode = 12; szError = e.what();