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 @@
\ 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();