Merge branch 'dev' into duke
This commit is contained in:
@@ -1,5 +1,86 @@
|
||||
Coding
|
||||
====================
|
||||
# Fresh sync
|
||||
|
||||
Many times, you will want to do a "fresh sync" test, to verify code works when syncing from the genesis block, which is a different code path than a "partial sync" which means you already have part of blockchain history and are "catching up" to get in sync.
|
||||
|
||||
A "fresh sync" goes thru the Initial Blockchain Download (IBD) optimized codepath and is often faster than than rescanning all of history. Fresh sync and partial sync testing any important change should be done for all important changes.
|
||||
|
||||
A fresh sync preserves peers.dat, so it will always be faster than a "fresh clone", which has to learn enough p2p peers to being syncing, which can often add many minutes to completing a sync. When code related to peers.dat changes (such in the `p2p` branch) then doing a fresh clone is needed to fully test it.
|
||||
|
||||
One way to do a fresh sync is:
|
||||
|
||||
```
|
||||
cd ~/.komodo/HUSH3
|
||||
rm blocks chainstate database notarizations hushstate
|
||||
```
|
||||
|
||||
If you are using `zindex=1` then you need to also delete zindex.dat
|
||||
|
||||
```
|
||||
cd ~/.komodo/HUSH3
|
||||
rm zindex.dat blocks chainstate database notarizations hushstate
|
||||
```
|
||||
|
||||
It's possible to confused hush if you ran old code, stop, restart, and then write out zindex.dat that is incorrect, with later hushds will load from disk and believe.
|
||||
|
||||
|
||||
# Testing a Branch
|
||||
|
||||
To test a branch called `zindexdb` with a fresh clone:
|
||||
|
||||
```
|
||||
# TODO: this should probably become a script in ./contrib
|
||||
git clone https://git.hush.is/hush/hush3 hush3-testing
|
||||
cd hush3-testing
|
||||
git checkout zindexdb
|
||||
# you need 2GB RAM free per -jN
|
||||
./build.sh -j2; make; make; make # this deals with build-system race condition bugs
|
||||
|
||||
# we want to test a fresh sync, so backup current data
|
||||
TIME=`perl -e "print time"`
|
||||
mv ~/.komodo/{HUSH3,HUSH3-backup-$TIME}
|
||||
mkdir ~/.komodo/HUSH3
|
||||
|
||||
# Use your previous config as a base
|
||||
cp ~/.komodo/{HUSH3-backup-$TIME,HUSH3}/HUSH3.conf
|
||||
# Add zindex to your node
|
||||
echo "zindex=1" >> ~/.komodo/HUSH3/HUSH3.conf
|
||||
|
||||
|
||||
# This is optional but will likely speed up sync time greatly
|
||||
cp ~/.komodo/{HUSH3-backup,HUSH3}/peers.dat
|
||||
|
||||
# This log file is helpful for debugging more and will contain a history of the
|
||||
# size of the anonset at every block height
|
||||
./src/hushd &> hushd.log &
|
||||
# to look at the log
|
||||
tail -f hushd.log
|
||||
```
|
||||
|
||||
To get a CSV file of the value of the anonset size for every block height:
|
||||
```
|
||||
grep anonset hushd.log | cut -d= -f2 > anonset.csv
|
||||
```
|
||||
|
||||
This only needs to be calculated once, if we can verify it's correct. These are historical values that do not change. The goal is a web page with a historical view of the HUSH anonset size.
|
||||
|
||||
|
||||
These values should match on all nodes:
|
||||
|
||||
```
|
||||
46913,2547,2253,294
|
||||
46914,2549,2254,295
|
||||
46915,2549,2254,295
|
||||
46916,2553,2257,296
|
||||
46917,2553,2257,296
|
||||
```
|
||||
|
||||
We should also check a recent block height to verify it's working correctly. The big "test" for this `zindexdb` branch is:
|
||||
|
||||
* If you stop a node, and restart, are the stats from `getchaintxtstats` correct, i.e. the anonset stats? For instance, `shielded_pool_size` should be close to 500000, if it's close to or exactly 0, something is wrong.
|
||||
* Is there a new file called `zindex.dat` in `~/.komodo/HUSH3/` ?
|
||||
* Is `zindex.dat` 149 bytes ?
|
||||
|
||||
# Coding
|
||||
|
||||
Various coding styles have been used during the history of the codebase,
|
||||
and the result is not very consistent. However, we're now trying to converge to
|
||||
@@ -36,59 +117,6 @@ class Class
|
||||
}
|
||||
```
|
||||
|
||||
Doxygen comments
|
||||
-----------------
|
||||
|
||||
To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
|
||||
|
||||
For example, to describe a function use:
|
||||
```c++
|
||||
/**
|
||||
* ... text ...
|
||||
* @param[in] arg1 A description
|
||||
* @param[in] arg2 Another argument description
|
||||
* @pre Precondition for function...
|
||||
*/
|
||||
bool function(int arg1, const char *arg2)
|
||||
```
|
||||
A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html.
|
||||
As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't
|
||||
*need* to provide any commands for a comment to be valid; just a description text is fine.
|
||||
|
||||
To describe a class use the same construct above the class definition:
|
||||
```c++
|
||||
/**
|
||||
* Alerts are for notifying old versions if they become too obsolete and
|
||||
* need to upgrade. The message is displayed in the status bar.
|
||||
* @see GetWarnings()
|
||||
*/
|
||||
class CAlert
|
||||
{
|
||||
```
|
||||
|
||||
To describe a member or variable use:
|
||||
```c++
|
||||
int var; //!< Detailed description after the member
|
||||
```
|
||||
|
||||
Also OK:
|
||||
```c++
|
||||
///
|
||||
/// ... text ...
|
||||
///
|
||||
bool function2(int arg1, const char *arg2)
|
||||
```
|
||||
|
||||
Not OK (used plenty in the current source, but not picked up):
|
||||
```c++
|
||||
//
|
||||
// ... text ...
|
||||
//
|
||||
```
|
||||
|
||||
A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
|
||||
but if possible use one of the above styles.
|
||||
|
||||
Development tips and tricks
|
||||
---------------------------
|
||||
|
||||
|
||||
12
doc/privacy-basics.md
Normal file
12
doc/privacy-basics.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Privacy Basics
|
||||
|
||||
## Browser Tips
|
||||
|
||||
Firefox is likely the best browser for privacy. Use this to improve + customize:
|
||||
|
||||
https://ebin.city/~werwolf/posts/firefox-hardening-guide/
|
||||
|
||||
which is a guide around using and customizing the [Arkenfox](https://github.com/arkenfox/user.js/wiki/1.3-Implementation) user.js project
|
||||
|
||||
Those are helpful when NOT using a Tor browser. If you are using Tor Browser (which is a fork of Firefox), then you do not need the above guide and should probably use the default that Tor Browser devs provide.
|
||||
|
||||
16
src/chain.h
16
src/chain.h
@@ -266,7 +266,7 @@ public:
|
||||
int64_t nPayments;
|
||||
|
||||
//! (memory only) Number of shielded transactions (of any kind) in the block up to and including this block.
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 ShieldedInput or ShieldedOutput
|
||||
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
|
||||
//! inputs and outputs.
|
||||
int64_t nShieldedTx;
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
int64_t nShieldedSpends;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
//! as a transaction containing only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
int64_t nFullyShieldedTx;
|
||||
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
int64_t nFullyShieldedPayments;
|
||||
|
||||
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent output.
|
||||
//! as a transaction containing ShieldedInputs and at least one transparent output.
|
||||
int64_t nDeshieldingTx;
|
||||
|
||||
//! (memory only) Number of deshielding payments. A deshielding payment is defined
|
||||
@@ -303,7 +303,7 @@ public:
|
||||
int64_t nDeshieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielding transactions. A shielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent input
|
||||
//! as a transaction containing ShieldedOutputs and at least one transparent input
|
||||
// i.e. t->z or t->(z,t) or z->(z,z,t)
|
||||
int64_t nShieldingTx;
|
||||
|
||||
@@ -322,7 +322,7 @@ public:
|
||||
int64_t nChainPayments;
|
||||
|
||||
//! (memory only) Number of shielded transactions (of any kind) in the chain up to and including this block.
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 ShieldedInput or ShieldedOutput
|
||||
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
|
||||
//! inputs and outputs.
|
||||
int64_t nChainShieldedTx;
|
||||
@@ -334,7 +334,7 @@ public:
|
||||
int64_t nChainShieldedSpends;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
//! as a transaction containing and only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
int64_t nChainFullyShieldedTx;
|
||||
|
||||
@@ -351,7 +351,7 @@ public:
|
||||
int64_t nChainFullyShieldedPayments;
|
||||
|
||||
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent output.
|
||||
//! as a transaction containing ShieldedInputs and at least one transparent output.
|
||||
int64_t nChainDeshieldingTx;
|
||||
|
||||
//! (memory only) Number of deshielding payments. A deshielding payment is defined
|
||||
@@ -359,7 +359,7 @@ public:
|
||||
int64_t nChainDeshieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielding transactions. A shielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent input
|
||||
//! as a transaction containing ShieldedOutputs and at least one transparent input
|
||||
// i.e. t->z or t->(z,t) or z->(z,z,t)
|
||||
int64_t nChainShieldingTx;
|
||||
|
||||
|
||||
@@ -783,11 +783,79 @@ void *chainparams_commandline() {
|
||||
(492000, uint256S("0x00000013bbbff98ddab19a3178a0088a20628791e94963e5d1ea635015dfa9c6"))
|
||||
(493000, uint256S("0x00000001ed829c061ba14f6953e79d99577079adf5526f1e43e6dc9d9f9571bf"))
|
||||
(494000, uint256S("0x00000018dfeced2d1584a1003fefa4349810239bade096e53b4fa6bbc38a1685"))
|
||||
(495000, uint256S("0x0000001816af55724cd49c0bfe02c9eac29b4a73db2b7d868b958218a03e6c94"))
|
||||
(496000, uint256S("0x000000007e2019c5246db5a75122c6826822fa154d68a51eee2ff23f54ec668e")),
|
||||
(int64_t) 1618760194, // time of last checkpointed block
|
||||
(int64_t) 842496, // total txs
|
||||
(double) 1812 // txs in the last day before block 496013
|
||||
(495000, uint256S("0x0000001816af55724cd49c0bfe02c9eac29b4a73db2b7d868b958218a03e6c94"))
|
||||
(496000, uint256S("0x000000007e2019c5246db5a75122c6826822fa154d68a51eee2ff23f54ec668e"))
|
||||
(497000, uint256S("0x0000000aa5803c0825cfa1a34227d0ecb80be191674365a372f71611eacdc742"))
|
||||
(498000, uint256S("0x000000166385022d4b4ade0921a5f6c7d4aec56257cd679f7c441aeb0552b28c"))
|
||||
(499000, uint256S("0x0000002ce5e48efb664e936c9551b2781c742416e519d3a023d087036519507b"))
|
||||
(500000, uint256S("0x0000000cdfe9389bde0e9f1d649dd2f19ee69d765b00907aa681c3cdaad0bdb6"))
|
||||
(501000, uint256S("0x00000028736fd4ce6995a46d217c0022d2882165b5f716e94f255877c73f474a"))
|
||||
(502000, uint256S("0x000000459520215ade21db91a83ad47a806320ba3e290d686149bcf5672e132a"))
|
||||
(503000, uint256S("0x000000086aee5827d0254e1176a4dfd5c8a7958ee1f61458bdb1eb4d6ffbc131"))
|
||||
(504000, uint256S("0x000000474906b6ad537fe14eca1316c7be23f181bc554a2244c97634a6d361a7"))
|
||||
(505000, uint256S("0x00000035db569efc139988b7d506529bb482284bf2dfc40060159b321883974d"))
|
||||
(506000, uint256S("0x0000000c55ddd54e1f0aa6a59abe774f0e14501743c2594184772031f5bf51fd"))
|
||||
(507000, uint256S("0x000000061ca0ea34d5d3ddd5d8ceb0dcf9a0720483efd98155c0aa3774387e60"))
|
||||
(508000, uint256S("0x00000004bd6cdfbbee3945b897c4d6b6f49199d788151fe5536417d31d2f36ab"))
|
||||
(509000, uint256S("0x0000000b73f9dd08528827a8224decf6635462d2adabac9301e5c17b7a24a5f4"))
|
||||
(510000, uint256S("0x00000004c41a5b61302564abc741195c915fdf9edd12669f93ac5d4443613664"))
|
||||
(511000, uint256S("0x000000094319bb7199e5697e458520e95639dcec5180d4442e1470f48feaf125"))
|
||||
(512000, uint256S("0x00000014516f2d52467edd913c52e1742ca8a767debd9294bbbf8f39bdbae506"))
|
||||
(513000, uint256S("0x000000177739b5379d196b74faeaabf35dbb9d3f6f9e172f659f68b3288a71c3"))
|
||||
(514000, uint256S("0x0000000940533509d21f249ab0b0144923e65050a24dbf53863c9c07fd21fd6b"))
|
||||
(515000, uint256S("0x000000007d256fc4cbfff1c05f83550b8dfdf093b060a98fafac6a090e349bc1"))
|
||||
(516000, uint256S("0x000000029ee7abc14842e22b4f3e7e3c640c55fa2a898773c83ff34ceb2a5482"))
|
||||
(517000, uint256S("0x00000019ca7705b4a8b35ae1aa4071401ed1de7449306ef8a34716637f43c2f1"))
|
||||
(518000, uint256S("0x00000013f4aa06fca6c2a57e80c3950d0e7613f3bcba0b52887d4c7579e5b20a"))
|
||||
(519000, uint256S("0x0000000b7d1e4efbbb38c91e838a50876be93a6549fdaeb534ec1d8657117e69"))
|
||||
(520000, uint256S("0x00000000c2fb98b56bf9c549406710b57308081663230a477c7b5983720a456a"))
|
||||
(521000, uint256S("0x0000000d48660709c9fd60f01b71260e0e6ba3875cdb109b7b037ec6b80f3098"))
|
||||
(522000, uint256S("0x00000019d0ad6bdebc9d39a5b9a6ae4d844b45bbfcdd97885841a1d8033c956f"))
|
||||
(523000, uint256S("0x000000121da004ec14c89b67151439765a19aadbdf4d4feca701cce7c3820efb"))
|
||||
(524000, uint256S("0x00000003d3445c4cb6e980751cd8119679d572f57bbaa3b9c9114e397841827e"))
|
||||
(525000, uint256S("0x0000000b2a079f083c86f9ab8b0f73dc511c20f6aa44d7735f29409df966f026"))
|
||||
(526000, uint256S("0x00000004d3ae427a98336ee4bc5e60f00ebd4c88f9ffdd18003f17535465888a"))
|
||||
(527000, uint256S("0x000000057e5cb13f42332f59b6c2d6f333369b8e4d9bdf6fa9bb441e2ddb5c51"))
|
||||
(528000, uint256S("0x000000045f51825c19aab9d1d620d7073c2114ccf3e40f63d66c729c71c2bc05"))
|
||||
(529000, uint256S("0x000000116ac2795cdbde2d3af6d804d9dbf445d2ed12d7cf13c155540f10c119"))
|
||||
(530000, uint256S("0x0000000be4932b469923d826991810109f2c2ca50d5fa0133c765b5ab96bf315"))
|
||||
(531000, uint256S("0x0000000a7fdd8ce073da5d95fcbefba5d0366c9b834cac914889108094d0cd18"))
|
||||
(532000, uint256S("0x0000000600d2ea28f32220c054e2ae66ec8471a2f755ef219a0c81e4a4296135"))
|
||||
(533000, uint256S("0x0000000a5f4a460970f6dcd3a271315f936648c854c1a7bb251dbc7996f90e92"))
|
||||
(534000, uint256S("0x00000009b5d0615eb98f06820cc6d66af542b8bbde0cabe5b54b6e7625e77803"))
|
||||
(535000, uint256S("0x0000000ac06f5d79b927f2dfb54eecd72f9ada28fa59092f5c3c83627b281605"))
|
||||
(536000, uint256S("0x000000037a51adb2cccf29b9c164386c8418959db16606b70a1389fb8755829f"))
|
||||
(537000, uint256S("0x0000000a129157792e233e233f85693625abb14be90362ff727ab97e8d5ec340"))
|
||||
(538000, uint256S("0x00000015e13085045c090a51e9c1114749fa7b465009f2ad70ff278d9ae05b5c"))
|
||||
(539000, uint256S("0x00000001953384069e477f7e1839dc0498cbeb951adb32bcbf3b96ef487fce4a"))
|
||||
(540000, uint256S("0x0000000281246b5d2e845aa711b6af76c8cc0d1f39ba25fe414f83bbe47544bb"))
|
||||
(541000, uint256S("0x0000000f27b777a942d6317438836258c4e34bd3761736a2b32cc2b7c8305d71"))
|
||||
(542000, uint256S("0x00000005d4667fb45a862d91ba843acbaee033915bf75536c67aeca1a2a3a5ff"))
|
||||
(543000, uint256S("0x0000000509b08619049b1aec8e715d971b8dbc2175acf7874a37b9ce13dfb137"))
|
||||
(544000, uint256S("0x0000000582563d79bf72a925ae3bc5c6f0eacbdb317c92fa89eb56d570427fd7"))
|
||||
(545000, uint256S("0x0000000ff9df3d3a00d682f069819acbc5697b42da69a78f6e07486ac68f0e49"))
|
||||
(546000, uint256S("0x00000004653460c603fa7a70292a85e286272b587f0b9cea7e73b765e8b0ef7b"))
|
||||
(547000, uint256S("0x000000074c5f411190c5bf788a37a00506935015df4872cc5471416abadb757d"))
|
||||
(548000, uint256S("0x00000005444a4ecd1eea940ad5395f2f7839967ee5b01be4a9b68755de4395ac"))
|
||||
(549000, uint256S("0x0000000216eafee0e40374b8e8db63118cb4e3adc3159068bdafff1f0e0d9deb"))
|
||||
(550000, uint256S("0x0000000056b84bc88604b9df668b60c020a6926b2dfdcd09955e5d8d3e7a5ca7"))
|
||||
(551000, uint256S("0x0000000adaaeb79c5c6c49038d7206f88d5b4ecaaf21aaca09b5a7d548f76b25"))
|
||||
(552000, uint256S("0x00000004185669b566e62cbebc9c50930c8ae0d5c42f23280262a7f55b726553"))
|
||||
(553000, uint256S("0x00000010112434cdb0203a053e0c22ef16b9d39b8feed2328d7ff97013b216be"))
|
||||
(554000, uint256S("0x00000006dacee96c0f48fc7250c71cc1e746befa84af8cd2ed0499d8d24cc6cb"))
|
||||
(555000, uint256S("0x00000001b3b2c149029d5a2e7cedb0683c97692a52cbc91bb532cb78bbcadcc0"))
|
||||
(556000, uint256S("0x0000000397bdd61939cc3d2c39360c5e3713ef9dd82b8cedac17075b8e177304"))
|
||||
(557000, uint256S("0x0000000414bb81b82a2e71608086ac585dba19ca249067c9e967d6f44a1d3163"))
|
||||
(558000, uint256S("0x00000003516d27423b1b5b60eab97d425e7be3f08f14bafd935666b1e955608e"))
|
||||
(559000, uint256S("0x00000005c44ef4543da5924e65f0fd2d2c8fe926b2f3995b83ccfd1463b443d7"))
|
||||
(560000, uint256S("0x00000002eb33454ba48e61a50351686115c47cb59b8fb0496432ad58e0484acf"))
|
||||
(561000, uint256S("0x00000004172d5940c07ec6d493e410fbab8a05dc73e350505e1540d7336eb353"))
|
||||
(562000, uint256S("0x00000000d9caaf66ad7782046886d3bfdf966c0a015dbae64042cd0c35e516e4"))
|
||||
(563000, uint256S("0x000000000d953e53c65145bfb41ba544a9ce9e5432c9ed8eabd39873dfcb8ab0"))
|
||||
(564000, uint256S("0x0000000d49258678c42bc2ea6f9e5d1206c578da8dc564d1a6114ce68bf77817")),
|
||||
(int64_t) 1623979514, // time of last checkpointed block
|
||||
(int64_t) 922687, // total txs
|
||||
(double) 1219 // txs in the last day before block 564690
|
||||
|
||||
};
|
||||
} else {
|
||||
|
||||
@@ -467,6 +467,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-opretmintxfee=<amt>", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 ));
|
||||
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-rescanheight", _("Rescan from specified height when rescan=1 on startup"));
|
||||
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
|
||||
@@ -2074,6 +2075,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
{
|
||||
pwalletMain->ClearNoteWitnessCache();
|
||||
pindexRescan = chainActive.Genesis();
|
||||
int rescanHeight = GetArg("-rescanheight", 0);
|
||||
if (rescanHeight > 0) {
|
||||
if (rescanHeight > chainActive.Tip()->GetHeight()) {
|
||||
pindexRescan = chainActive.Tip();
|
||||
} else {
|
||||
pindexRescan = chainActive[rescanHeight];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CBlockLocator locator;
|
||||
|
||||
157
src/main.cpp
157
src/main.cpp
@@ -76,6 +76,7 @@ using namespace std;
|
||||
CCriticalSection cs_main;
|
||||
extern uint8_t NOTARY_PUBKEY33[33];
|
||||
extern int32_t HUSH_LOADINGBLOCKS,HUSH_LONGESTCHAIN,HUSH_INSYNC,HUSH_CONNECTING,HUSH_EXTRASATOSHI;
|
||||
extern CZindexStats zstats;
|
||||
int32_t HUSH_NEWBLOCKS;
|
||||
int32_t hush_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
||||
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||
@@ -572,6 +573,102 @@ namespace {
|
||||
|
||||
} // anon namespace
|
||||
|
||||
// CZindexDB
|
||||
CZindexDB::CZindexDB()
|
||||
{
|
||||
pathAddr = GetDataDir() / "zindex.dat";
|
||||
}
|
||||
|
||||
bool CZindexDB::Read(CZindexStats& zstats)
|
||||
{
|
||||
// open input file, and associate with CAutoFile
|
||||
FILE *file = fopen(pathAddr.string().c_str(), "rb");
|
||||
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
|
||||
if (filein.IsNull())
|
||||
return error("%s: Failed to open file %s", __func__, pathAddr.string());
|
||||
|
||||
// use file size to size memory buffer
|
||||
int fileSize = boost::filesystem::file_size(pathAddr);
|
||||
int dataSize = fileSize - sizeof(uint256);
|
||||
// Don't try to resize to a negative number if file is small
|
||||
if (dataSize < 0)
|
||||
dataSize = 0;
|
||||
vector<unsigned char> vchData;
|
||||
vchData.resize(dataSize);
|
||||
uint256 hashIn;
|
||||
|
||||
// read data and checksum from file
|
||||
try {
|
||||
filein.read((char *)&vchData[0], dataSize);
|
||||
filein >> hashIn;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
return error("%s: Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
filein.fclose();
|
||||
|
||||
CDataStream ssZstats(vchData, SER_DISK, CLIENT_VERSION);
|
||||
|
||||
// verify stored checksum matches input data
|
||||
uint256 hashTmp = Hash(ssZstats.begin(), ssZstats.end());
|
||||
if (hashIn != hashTmp)
|
||||
return error("%s: zstats Checksum mismatch, data corrupted", __func__);
|
||||
|
||||
unsigned char pchMsgTmp[4];
|
||||
try {
|
||||
// de-serialize file header (network specific magic number) and ..
|
||||
ssZstats >> FLATDATA(pchMsgTmp);
|
||||
|
||||
// ... verify the network matches ours
|
||||
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
|
||||
return error("%s: Invalid network magic number", __func__);
|
||||
|
||||
// de-serialize data into one CZindexStats object
|
||||
ssZstats >> zstats;
|
||||
} catch (const std::exception& e) {
|
||||
return error("%s: Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CZindexDB::Write(const CZindexStats& zstats)
|
||||
{
|
||||
// Generate random temporary filename
|
||||
unsigned short randv = 0;
|
||||
GetRandBytes((unsigned char*)&randv, sizeof(randv));
|
||||
std::string tmpfn = strprintf("zindex.dat.%04x", randv);
|
||||
|
||||
// serialize zstats, checksum data up to that point, then append checksum
|
||||
CDataStream ssZstats(SER_DISK, CLIENT_VERSION);
|
||||
ssZstats << FLATDATA(Params().MessageStart());
|
||||
ssZstats << zstats;
|
||||
uint256 hash = Hash(ssZstats.begin(), ssZstats.end());
|
||||
ssZstats << hash;
|
||||
|
||||
// open temp output file, and associate with CAutoFile
|
||||
boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
|
||||
FILE *file = fopen(pathTmp.string().c_str(), "wb");
|
||||
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
|
||||
if (fileout.IsNull())
|
||||
return error("%s: Failed to open file %s", __func__, pathTmp.string());
|
||||
|
||||
// Write and commit header, data
|
||||
try {
|
||||
fileout << ssZstats;
|
||||
} catch (const std::exception& e) {
|
||||
return error("%s: Serialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
FileCommit(fileout.Get());
|
||||
fileout.fclose();
|
||||
|
||||
// replace existing zindex.dat, if any, with new zindex.dat.XXXX
|
||||
if (!RenameOver(pathTmp, pathAddr))
|
||||
return error("%s: Rename-into-place failed", __func__);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
|
||||
LOCK(cs_main);
|
||||
CNodeState *state = State(nodeid);
|
||||
@@ -3928,7 +4025,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
|
||||
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
|
||||
LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
|
||||
if ( HUSH_LONGESTCHAIN != 0 && (pindexNew->GetHeight() == HUSH_LONGESTCHAIN || pindexNew->GetHeight() == HUSH_LONGESTCHAIN+1) )
|
||||
if ( HUSH_LONGESTCHAIN != 0 && (pindexNew->GetHeight() >= HUSH_LONGESTCHAIN ))
|
||||
HUSH_INSYNC = (int32_t)pindexNew->GetHeight();
|
||||
else HUSH_INSYNC = 0;
|
||||
//fprintf(stderr,"connect.%d insync.%d ASSETCHAINS_SAPLING.%d\n",(int32_t)pindexNew->GetHeight(),HUSH_INSYNC,ASSETCHAINS_SAPLING);
|
||||
@@ -4429,13 +4526,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
// pool. So we invert the sign here.
|
||||
saplingValue += -tx.valueBalance;
|
||||
|
||||
/*
|
||||
for (auto js : tx.vjoinsplit) {
|
||||
sproutValue += js.vpub_old;
|
||||
sproutValue -= js.vpub_new;
|
||||
}
|
||||
*/
|
||||
|
||||
// Ignore following stats unless -zindex enabled
|
||||
if (!fZindex)
|
||||
continue;
|
||||
@@ -4560,6 +4650,39 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
if (fZdebug) {
|
||||
//fprintf(stderr,"%s: setting blockchain zstats with zspends=%d, zouts=%d\n", __FUNCTION__, nShieldedSpendsInBlock, nShieldedOutputsInBlock );
|
||||
}
|
||||
if (pindex->pprev) {
|
||||
// If chain stats are zero (such as after restart), load data from zindex.dat
|
||||
if (pindex->pprev->nChainNotarizations == 0)
|
||||
pindex->pprev->nChainNotarizations = zstats.nChainNotarizations;
|
||||
if (pindex->pprev->nChainShieldedTx == 0)
|
||||
pindex->pprev->nChainShieldedTx = zstats.nChainShieldedTx;
|
||||
if (pindex->pprev->nChainShieldedOutputs == 0)
|
||||
pindex->pprev->nChainShieldedOutputs = zstats.nChainShieldedOutputs;
|
||||
if (pindex->pprev->nChainShieldedSpends == 0) {
|
||||
pindex->pprev->nChainShieldedSpends = zstats.nChainShieldedSpends;
|
||||
// TODO: if zstats.nHeight != chainActive.Height() the stats will be off
|
||||
fprintf(stderr, "%s: loaded anonymity set of %li at stats height=%li vs local height=%d from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends, zstats.nHeight, chainActive.Height() );
|
||||
}
|
||||
if (pindex->pprev->nChainFullyShieldedTx == 0)
|
||||
pindex->pprev->nChainFullyShieldedTx = zstats.nChainFullyShieldedTx;
|
||||
if (pindex->pprev->nChainShieldingTx == 0)
|
||||
pindex->pprev->nChainShieldingTx = zstats.nChainShieldingTx;
|
||||
if (pindex->pprev->nChainDeshieldingTx == 0)
|
||||
pindex->pprev->nChainDeshieldingTx = zstats.nChainDeshieldingTx;
|
||||
if (pindex->pprev->nChainPayments == 0) {
|
||||
fprintf(stderr, "%s: setting nChainPayments=%li at height %d\n", __func__, zstats.nChainPayments, chainActive.Height() );
|
||||
pindex->pprev->nChainPayments = zstats.nChainPayments;
|
||||
}
|
||||
if (pindex->pprev->nChainShieldedPayments == 0)
|
||||
pindex->pprev->nChainShieldedPayments = zstats.nChainShieldedPayments;
|
||||
if (pindex->pprev->nChainFullyShieldedPayments == 0)
|
||||
pindex->pprev->nChainFullyShieldedPayments = zstats.nChainFullyShieldedPayments;
|
||||
if (pindex->pprev->nChainShieldingPayments == 0)
|
||||
pindex->pprev->nChainShieldingPayments = zstats.nChainShieldingPayments;
|
||||
if (pindex->pprev->nChainDeshieldingPayments == 0)
|
||||
pindex->pprev->nChainDeshieldingPayments = zstats.nChainDeshieldingPayments;
|
||||
}
|
||||
|
||||
pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations;
|
||||
pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx;
|
||||
pindex->nChainShieldedOutputs = (pindex->pprev ? pindex->pprev->nChainShieldedOutputs : 0) + pindex->nShieldedOutputs;
|
||||
@@ -4572,6 +4695,23 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
pindex->nChainFullyShieldedPayments = (pindex->pprev ? pindex->pprev->nChainFullyShieldedPayments : 0) + pindex->nFullyShieldedPayments;
|
||||
pindex->nChainShieldingPayments = (pindex->pprev ? pindex->pprev->nChainShieldingPayments : 0) + pindex->nShieldingPayments;
|
||||
pindex->nChainDeshieldingPayments = (pindex->pprev ? pindex->pprev->nChainDeshieldingPayments : 0) + pindex->nDeshieldingPayments;
|
||||
|
||||
// Update in-memory structure that gets serialized to zindex.dat
|
||||
zstats.nHeight = pindex->GetHeight();
|
||||
zstats.nChainNotarizations = pindex->nChainNotarizations ;
|
||||
zstats.nChainShieldedTx = pindex->nChainShieldedTx ;
|
||||
zstats.nChainShieldedOutputs = pindex->nChainShieldedOutputs ;
|
||||
zstats.nChainShieldedSpends = pindex->nChainShieldedSpends ;
|
||||
zstats.nChainFullyShieldedTx = pindex->nChainFullyShieldedTx ;
|
||||
zstats.nChainShieldingTx = pindex->nChainShieldingTx ;
|
||||
zstats.nChainDeshieldingTx = pindex->nChainDeshieldingTx ;
|
||||
zstats.nChainPayments = pindex->nChainPayments ;
|
||||
zstats.nChainShieldedPayments = pindex->nChainShieldedPayments ;
|
||||
zstats.nChainFullyShieldedPayments = pindex->nChainFullyShieldedPayments ;
|
||||
zstats.nChainShieldingPayments = pindex->nChainShieldingPayments ;
|
||||
zstats.nChainDeshieldingPayments = pindex->nChainDeshieldingPayments ;
|
||||
fprintf(stderr,"%s: setting zstats with height,zouts,zspends,anonset=%li,%li,%li,%li\n", __FUNCTION__, zstats.nHeight, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends);
|
||||
|
||||
}
|
||||
|
||||
if (pindex->pprev) {
|
||||
@@ -4610,6 +4750,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fZindex)
|
||||
fprintf(stderr, "ht.%d, ShieldedPayments=%d, ShieldedTx=%d, ShieldedOutputs=%d, FullyShieldedTx=%d, ntz=%d\n",
|
||||
pindexNew->GetHeight(), nShieldedPayments, nShieldedTx, nShieldedOutputs, nFullyShieldedTx, nNotarizations );
|
||||
|
||||
110
src/main.h
110
src/main.h
@@ -950,4 +950,114 @@ std::pair<std::map<CBlockIndex*, std::list<CTransaction>>, uint64_t> DrainRecent
|
||||
void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence);
|
||||
bool ChainIsFullyNotified();
|
||||
|
||||
class CZindexStats
|
||||
{
|
||||
//private:
|
||||
public:
|
||||
int64_t nHeight;
|
||||
int64_t nChainTx;
|
||||
int64_t nChainNotarizations;
|
||||
int64_t nChainPayments;
|
||||
int64_t nChainShieldedTx;
|
||||
int64_t nChainShieldedOutputs;
|
||||
int64_t nChainShieldedSpends;
|
||||
int64_t nChainFullyShieldedTx;
|
||||
int64_t nChainShieldingPayments;
|
||||
int64_t nChainShieldedPayments;
|
||||
int64_t nChainFullyShieldedPayments;
|
||||
int64_t nChainDeshieldingTx;
|
||||
int64_t nChainDeshieldingPayments;
|
||||
int64_t nChainShieldingTx;
|
||||
|
||||
size_t Height() const
|
||||
{
|
||||
return nHeight;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
LOCK(cs_main);
|
||||
nChainTx=0;
|
||||
nChainNotarizations=0;
|
||||
nChainPayments=0;
|
||||
nChainShieldedTx=0;
|
||||
nChainShieldedOutputs=0;
|
||||
nChainShieldedSpends=0;
|
||||
nChainFullyShieldedTx=0;
|
||||
nChainShieldingPayments=0;
|
||||
nChainShieldedPayments=0;
|
||||
nChainFullyShieldedPayments=0;
|
||||
nChainDeshieldingTx=0;
|
||||
nChainDeshieldingPayments=0;
|
||||
nChainShieldingTx=0;
|
||||
}
|
||||
|
||||
CZindexStats()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~CZindexStats()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Stream> void Serialize(Stream &s) const
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
// So we can detect a new version and force a rescan
|
||||
unsigned char nVersion = 1;
|
||||
s << nVersion;
|
||||
s << nHeight;
|
||||
s << nChainTx;
|
||||
s << nChainNotarizations;
|
||||
s << nChainPayments;
|
||||
s << nChainShieldedTx;
|
||||
s << nChainShieldedOutputs;
|
||||
s << nChainShieldedSpends;
|
||||
s << nChainFullyShieldedTx;
|
||||
s << nChainShieldingPayments;
|
||||
s << nChainShieldedPayments;
|
||||
s << nChainFullyShieldedPayments;
|
||||
s << nChainDeshieldingTx;
|
||||
s << nChainDeshieldingPayments;
|
||||
s << nChainShieldingTx;
|
||||
}
|
||||
|
||||
template<typename Stream> void Unserialize(Stream& s)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
Clear();
|
||||
unsigned char nVersion;
|
||||
s >> nVersion;
|
||||
s >> nHeight;
|
||||
s >> nChainTx;
|
||||
s >> nChainNotarizations;
|
||||
s >> nChainPayments;
|
||||
s >> nChainShieldedTx;
|
||||
s >> nChainShieldedOutputs;
|
||||
s >> nChainShieldedSpends;
|
||||
s >> nChainFullyShieldedTx;
|
||||
s >> nChainShieldingPayments;
|
||||
s >> nChainShieldedPayments;
|
||||
s >> nChainFullyShieldedPayments;
|
||||
s >> nChainDeshieldingTx;
|
||||
s >> nChainDeshieldingPayments;
|
||||
s >> nChainShieldingTx;
|
||||
}
|
||||
};
|
||||
|
||||
// Wrapper for zindex.dat stats
|
||||
class CZindexDB
|
||||
{
|
||||
private:
|
||||
boost::filesystem::path pathAddr;
|
||||
public:
|
||||
CZindexDB();
|
||||
bool Write(const CZindexStats& zstats);
|
||||
bool Read(CZindexStats& zstats);
|
||||
};
|
||||
|
||||
|
||||
#endif // HUSH_MAIN_H
|
||||
|
||||
77
src/net.cpp
77
src/net.cpp
@@ -48,6 +48,11 @@ using namespace hush;
|
||||
// Satoshi originally used 10 seconds(!), did they know something Peter Wuille didn't?
|
||||
#define DUMP_ADDRESSES_INTERVAL 300
|
||||
|
||||
// This is every 2 blocks, on avg, on HUSH3
|
||||
#define DUMP_ZINDEX_INTERVAL 150
|
||||
|
||||
#define CHECK_PLZ_STOP_INTERVAL 120
|
||||
|
||||
#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@@ -89,10 +94,10 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Global state variables
|
||||
extern uint16_t ASSETCHAINS_P2PPORT;
|
||||
extern char SMART_CHAIN_SYMBOL[65];
|
||||
|
||||
bool fDiscover = true;
|
||||
bool fListen = true;
|
||||
uint64_t nLocalServices = NODE_NETWORK | NODE_NSPV;
|
||||
@@ -103,11 +108,14 @@ static CNode* pnodeLocalHost = NULL;
|
||||
uint64_t nLocalHostNonce = 0;
|
||||
static std::vector<ListenSocket> vhListenSocket;
|
||||
CAddrMan addrman;
|
||||
CZindexStats zstats;
|
||||
int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
|
||||
bool fAddressesInitialized = false;
|
||||
std::string strSubVersion;
|
||||
TLSManager tlsmanager = TLSManager();
|
||||
|
||||
extern void StartShutdown();
|
||||
|
||||
vector<CNode*> vNodes;
|
||||
CCriticalSection cs_vNodes;
|
||||
map<CInv, CDataStream> mapRelay;
|
||||
@@ -1400,6 +1408,28 @@ void DumpAddresses()
|
||||
LogPrint("net", "Flushed %d addresses to peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
void DumpZindexStats()
|
||||
{
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
||||
CZindexDB zdb;
|
||||
zdb.Write(zstats);
|
||||
|
||||
LogPrintf("Flushed stats at height %li to zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
void CheckIfWeShouldStop()
|
||||
{
|
||||
// If the RPC interface is "stuck", such as filling up with deadlocks
|
||||
// and cannot process any more requests, the only option was to kill the full node.
|
||||
// This is a disk-based method where a node can realize it should stop, and which
|
||||
// can help avoid extremely long rescans
|
||||
if(boost::filesystem::exists(GetDataDir() / "plz_stop")) {
|
||||
LogPrintf("%s: Found plz_stop file, shutting down...\n", __func__);
|
||||
StartShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void static ProcessOneShot()
|
||||
{
|
||||
string strDest;
|
||||
@@ -1909,8 +1939,40 @@ void static Discover(boost::thread_group& threadGroup)
|
||||
#endif
|
||||
}
|
||||
|
||||
//extern CWallet pwalletMain;
|
||||
void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
{
|
||||
|
||||
CheckIfWeShouldStop();
|
||||
|
||||
if (fZindex) {
|
||||
uiInterface.InitMessage(_("Loading zindex stats..."));
|
||||
int64_t nStart = GetTimeMillis();
|
||||
{
|
||||
CZindexDB zdb;
|
||||
if (!zdb.Read(zstats)) {
|
||||
// The first time nodes use zindex.dat code, no file will be found
|
||||
// TODO: rescan if invalid only
|
||||
LogPrintf("Invalid or missing zindex.dat! Generating new...\n");
|
||||
|
||||
//bool update = true;
|
||||
//pwalletMain->ScanForWalletTransactions(chainActive.Genesis(),update);
|
||||
|
||||
// We assume this is the first startup with zindex.dat code, and serialize current data to disk.
|
||||
DumpZindexStats();
|
||||
|
||||
// Now read-in the stats we just wrote to disk to memory
|
||||
if(!zdb.Read(zstats)) {
|
||||
LogPrintf("Invalid or missing zindex.dat! Stats may be corrupt\n");
|
||||
} else {
|
||||
LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart);
|
||||
}
|
||||
} else {
|
||||
LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Loading addresses..."));
|
||||
// Load addresses for peers.dat
|
||||
int64_t nStart = GetTimeMillis();
|
||||
@@ -1919,8 +1981,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
if (!adb.Read(addrman))
|
||||
LogPrintf("Invalid or missing peers.dat! This can happen when upgrading. Whatevz, recreating\n");
|
||||
}
|
||||
LogPrintf("Loaded %i addresses from peers.dat %dms\n",
|
||||
addrman.size(), GetTimeMillis() - nStart);
|
||||
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
|
||||
fAddressesInitialized = true;
|
||||
|
||||
if (semOutbound == NULL) {
|
||||
@@ -1968,6 +2029,13 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
// Dump network addresses
|
||||
scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL);
|
||||
|
||||
// Dump zindex stats if -zindex is enabled
|
||||
if (fZindex) {
|
||||
scheduler.scheduleEvery(&DumpZindexStats, DUMP_ZINDEX_INTERVAL);
|
||||
}
|
||||
|
||||
scheduler.scheduleEvery(&CheckIfWeShouldStop, CHECK_PLZ_STOP_INTERVAL);
|
||||
}
|
||||
|
||||
bool StopNode()
|
||||
@@ -1977,6 +2045,9 @@ bool StopNode()
|
||||
for (int i=0; i<(MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++)
|
||||
semOutbound->post();
|
||||
|
||||
// persist current zindex stats to disk before we exit
|
||||
DumpZindexStats();
|
||||
|
||||
if (HUSH_NSPV_FULLNODE && fAddressesInitialized)
|
||||
{
|
||||
DumpAddresses();
|
||||
|
||||
@@ -223,6 +223,7 @@ public:
|
||||
int nStartingHeight;
|
||||
uint64_t nSendBytes;
|
||||
uint64_t nRecvBytes;
|
||||
bool fRelayTxes;
|
||||
bool fAllowlisted; // If true this node bypasses DoS ban limits
|
||||
bool fFeeler; // If true this node is being used as a short lived feeler.
|
||||
double dPingTime;
|
||||
|
||||
@@ -1660,10 +1660,12 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 0 and the block's height - 1");
|
||||
}
|
||||
}
|
||||
LogPrintf("%s: blockcount = %d\n", __func__, blockcount);
|
||||
|
||||
const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->GetHeight() - blockcount);
|
||||
int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
|
||||
int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
|
||||
LogPrintf("%s: pindexPast.height = %d, pindex.height = %d\n", __func__, pindexPast->GetHeight(), pindex->GetHeight() );
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("time", (int64_t)pindex->nTime);
|
||||
@@ -1695,6 +1697,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
ret.pushKV("window_tx_count", nTxDiff);
|
||||
ret.pushKV("window_interval", nTimeDiff);
|
||||
int64_t nPaymentsDiff = pindex->nChainPayments - pindexPast->nChainPayments;
|
||||
LogPrintf("%s: pindexPast.nChainPayments = %d, pindex.nChainPayments = %d\n", __func__, pindexPast->nChainPayments, pindex->nChainPayments );
|
||||
int64_t nShieldedTxDiff = pindex->nChainShieldedTx - pindexPast->nChainShieldedTx;
|
||||
int64_t nShieldingTxDiff = pindex->nChainShieldingTx - pindexPast->nChainShieldingTx;
|
||||
int64_t nDeshieldingTxDiff = pindex->nChainDeshieldingTx - pindexPast->nChainDeshieldingTx;
|
||||
|
||||
@@ -95,6 +95,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
|
||||
" \"bytessent\": n, (numeric) The total bytes sent\n"
|
||||
" \"bytesrecv\": n, (numeric) The total bytes received\n"
|
||||
" \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n"
|
||||
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
" \"timeoffset\": ttt, (numeric) The time offset in seconds (deprecated, always 0)\n"
|
||||
" \"pingtime\": n, (numeric) ping time\n"
|
||||
@@ -146,6 +147,8 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
obj.push_back(Pair("lastrecv", stats.nLastRecv));
|
||||
obj.push_back(Pair("bytessent", stats.nSendBytes));
|
||||
obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
|
||||
obj.push_back(Pair("relaytxes", stats.fRelayTxes));
|
||||
|
||||
obj.push_back(Pair("conntime", stats.nTimeConnected));
|
||||
obj.push_back(Pair("timeoffset", 0));
|
||||
obj.push_back(Pair("pingtime", stats.dPingTime));
|
||||
@@ -177,15 +180,15 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
}
|
||||
|
||||
int32_t HUSH_LONGESTCHAIN;
|
||||
static int32_t hush_longest_depth = 0;
|
||||
int32_t hush_longestchain()
|
||||
{
|
||||
static int32_t depth;
|
||||
int32_t ht,n=0,num=0,maxheight=0,height = 0;
|
||||
if ( depth < 0 )
|
||||
depth = 0;
|
||||
if ( depth == 0 )
|
||||
if ( hush_longest_depth < 0 )
|
||||
hush_longest_depth = 0;
|
||||
if ( hush_longest_depth == 0 )
|
||||
{
|
||||
depth++;
|
||||
hush_longest_depth++;
|
||||
vector<CNodeStats> vstats;
|
||||
{
|
||||
//LOCK(cs_main);
|
||||
@@ -212,7 +215,7 @@ int32_t hush_longestchain()
|
||||
if ( ht > height )
|
||||
height = ht;
|
||||
}
|
||||
depth--;
|
||||
hush_longest_depth--;
|
||||
if ( num > (n >> 1) )
|
||||
{
|
||||
if ( 0 && height != HUSH_LONGESTCHAIN )
|
||||
|
||||
@@ -825,9 +825,13 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms
|
||||
{
|
||||
LOCK(cs_rpcWarmup);
|
||||
if (fRPCInWarmup) {
|
||||
// hush-cli stop is the only valid RPC command during warmup
|
||||
// We don't know if we have valid blocks or wallet yet, nothing else is safe
|
||||
if (pcmd->name != "stop") {
|
||||
// Most RPCs are unsafe to run during warmup, but stop+help are fine
|
||||
// Others may not have data loaded yet, such as wallet details, but
|
||||
// those RPCs are written defensively to deal with that. Allowing these
|
||||
// few RPCs means we can see our addresses and make private key backups
|
||||
// while a very long wallet rescan is happening
|
||||
if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" &&
|
||||
pcmd->name != "listaddresses" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) {
|
||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,7 +1103,7 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK
|
||||
if (fHelp || params.size() > 1 )
|
||||
throw runtime_error(
|
||||
"cleanwallettransactions \"txid\"\n"
|
||||
"\nRemove all txs that are spent. You can clear all txs bar one, by specifiying a txid.\n"
|
||||
"\nRemove all transparent UTXOs that are spent. You can clear all transactions bar one, by specifiying a txid.\n"
|
||||
"\nPlease backup your wallet.dat before running this command.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"txid\" (string, optional) The transaction id to keep.\n"
|
||||
@@ -1133,9 +1133,7 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK
|
||||
if ( !pwalletMain->IsMine(tmp_tx) )
|
||||
{
|
||||
throw runtime_error("\nThe transaction is not yours!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
@@ -1145,14 +1143,10 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
throw runtime_error("\nThe transaction could not be found!\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// get all locked utxos to relock them later.
|
||||
vector<COutPoint> vLockedUTXO;
|
||||
pwalletMain->ListLockedCoins(vLockedUTXO);
|
||||
|
||||
@@ -480,13 +480,19 @@ void CWallet::ChainTip(const CBlockIndex *pindex,
|
||||
pblock->GetBlockTime() > GetTime() - 144*ASSETCHAINS_BLOCKTIME)
|
||||
{
|
||||
BuildWitnessCache(pindex, false);
|
||||
RunSaplingConsolidation(pindex->GetHeight());
|
||||
DeleteWalletTransactions(pindex);
|
||||
if (fSaplingConsolidationEnabled) {
|
||||
RunSaplingConsolidation(pindex->GetHeight());
|
||||
}
|
||||
if (fTxDeleteEnabled) {
|
||||
DeleteWalletTransactions(pindex);
|
||||
}
|
||||
} else {
|
||||
//Build initial witnesses on every block
|
||||
BuildWitnessCache(pindex, true);
|
||||
if (initialDownloadCheck && pindex->GetHeight() % fDeleteInterval == 0) {
|
||||
DeleteWalletTransactions(pindex);
|
||||
if (fTxDeleteEnabled) {
|
||||
if (initialDownloadCheck && pindex->GetHeight() % fDeleteInterval == 0) {
|
||||
DeleteWalletTransactions(pindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -902,12 +908,15 @@ int64_t CWallet::NullifierCount()
|
||||
void CWallet::ClearNoteWitnessCache()
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
int notes = 0;
|
||||
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
|
||||
for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) {
|
||||
item.second.witnesses.clear();
|
||||
item.second.witnessHeight = -1;
|
||||
notes++;
|
||||
}
|
||||
}
|
||||
LogPrintf("%s: Cleared witness data from %d wallet items and %d SaplingNotes\n", __func__, mapWallet.size(), notes);
|
||||
}
|
||||
|
||||
void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex)
|
||||
@@ -1122,6 +1131,7 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
|
||||
nd->witnessHeight = pblockindex->GetHeight();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2378,12 +2388,6 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
|
||||
return pwalletdb->WriteTx(GetHash(), *this);
|
||||
}
|
||||
|
||||
void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
|
||||
std::vector<boost::optional<SproutWitness>>& witnesses,
|
||||
uint256 &final_anchor)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder the transactions based on block hieght and block index.
|
||||
* Transactions can get out of order when they are deleted and subsequently
|
||||
@@ -2734,8 +2738,10 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||
BuildWitnessCache(pindex, true);
|
||||
|
||||
//Delete Transactions
|
||||
if (pindex->GetHeight() % fDeleteInterval == 0)
|
||||
DeleteWalletTransactions(pindex);
|
||||
if (fTxDeleteEnabled) {
|
||||
if (pindex->GetHeight() % fDeleteInterval == 0)
|
||||
DeleteWalletTransactions(pindex);
|
||||
}
|
||||
|
||||
if (GetTime() >= nNow + 60) {
|
||||
nNow = GetTime();
|
||||
|
||||
@@ -1122,10 +1122,6 @@ public:
|
||||
void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
|
||||
void RescanWallet();
|
||||
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
|
||||
void WitnessNoteCommitment(
|
||||
std::vector<uint256> commitments,
|
||||
std::vector<boost::optional<SproutWitness>>& witnesses,
|
||||
uint256 &final_anchor);
|
||||
void ReorderWalletTransactions(std::map<std::pair<int,int>, CWalletTx*> &mapSorted, int64_t &maxOrderPos);
|
||||
void UpdateWalletTransactionOrder(std::map<std::pair<int,int>, CWalletTx*> &mapSorted, bool resetOrder);
|
||||
void DeleteTransactions(std::vector<uint256> &removeTxs);
|
||||
|
||||
Reference in New Issue
Block a user