-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
manage names tab merged against current master #187
base: master
Are you sure you want to change the base?
Conversation
Paging @randy-waterhouse and @domob1812 |
Thanks a lot for finishing this work - this will be great once launched! I'll take a look at the code now - and am already sorry for probably a lot of pedantic comments I'll have. ;) BTW, in the future, I think you should try to have fewer (or just one) commit in a PR - |
I know it's annoying to go through a million commits. I can squash it before we merge, if that's OK. Thanks for looking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good, I'm just very pedantic -- thanks for your hard work on this!
src/names/common.cpp
Outdated
@@ -6,6 +6,8 @@ | |||
|
|||
#include "script/names.h" | |||
|
|||
std::map<std::string, NameNewReturn > pendingNameFirstUpdate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting nit: I would remove the space between NameNewReturn
and the closing >
.
src/names/common.h
Outdated
@@ -10,6 +10,8 @@ | |||
#include "script/script.h" | |||
#include "serialize.h" | |||
|
|||
#include <univalue.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this include? I don't see anything in your additions that would require it - or is it required for something existing in the file and currently missing? Please either remove or briefly reply here with the explanation why you need the include.
src/names/common.h
Outdated
|
||
/* Here is where we store our pending name_firstupdates (see above) | ||
while we're waiting for name_new to confirm. */ | ||
extern std::map<std::string, NameNewReturn > pendingNameFirstUpdate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand your code correctly, you need this here rather than just in the UI code because it is part of the wallet, right? In that case, however, it should also be stored in the wallet and not in a global variable -- especially in light of the recent upstream changes to support multiple wallets in a single running client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this one, what do you think about this refactor strategy:
- move
pendingNameFirstUpdate
map to walletdb - move reads, writes, exists checks on
pendingNameFirstUpdate
to methods in walletdb - in the UI do the interaction through walletmodel (QT model) which wraps function calls to walletdb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, basically. I think you should add the variable to CWallet
, where for instance also mapWallet
is (since it is very similar in spirit, IMHO). Access should be through CWallet
, not walletdb, though. (The walletdb is the backing BDB, but from there you load it into memory just like you do now - except that you keep it in CWallet
and ideally do all access to it through the wallet. Do not access walletdb directly, let the wallet do it; at least that's how I think it works for transactions.)
I don't know how the UI typically interacts with the wallet, but I guess walletmodel is the correct way, yes. (In general, I think you should just follow how the wallet transactions are stored and handled, for instance.)
src/qt/bitcoinaddressvalidator.h
Outdated
@@ -15,9 +15,12 @@ class BitcoinAddressEntryValidator : public QValidator | |||
Q_OBJECT | |||
|
|||
public: | |||
explicit BitcoinAddressEntryValidator(QObject *parent); | |||
explicit BitcoinAddressEntryValidator(QObject *parent, bool fAllowEmpty = false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this change? I've not yet finished reading your code, but my guess is that you want an "allow empty" address field for name updates - is that correct, or do you need it for something else? (Apart from that, though, I have no idea how this could be related to adding the name UI.) Please briefly explain here for my understanding. Thanks!
src/qt/bitcoinaddressvalidator.h
Outdated
|
||
State validate(QString &input, int &pos) const; | ||
|
||
private: | ||
bool allowEmpty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think you can mark this as const
.
src/wallet/walletdb.cpp
Outdated
NameNewReturn ret; | ||
ret.hex = txid; | ||
ret.rand = rand; | ||
ret.data = pendingData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has me wonder about the serialisation of NameNewReturn
. You could actually define "proper" serialisation of the struct in the same way that other stuff in the code is serialised (e. g., transactions). That would fit better into the existing code here than using JSON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree and I'll add this to the list.
|
||
BOOST_FIXTURE_TEST_SUITE(wallet_name_pending_tests, WalletTestingSetup) | ||
|
||
BOOST_AUTO_TEST_CASE(wallet_name_pending_tests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing a unit test! :)
std::string nameBad = "test/baddata"; | ||
std::string txid = "9f73e1dfa3cbae23d008307e42e72beb8c010546ea2a7b9ff32619676a9c64a6"; | ||
std::string rand = "092abbca8a938103abcc"; | ||
std::string data = "{\"foo\": \"bar\"}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can all these be const?
|
||
// make sure we've added our pending name | ||
BOOST_CHECK(pendingNameFirstUpdate.size() == 1); | ||
BOOST_CHECK(pendingNameFirstUpdate.find(nameGood) != pendingNameFirstUpdate.end()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I personally would write the check as pendingNameFirstUpdate.count(nameGood) > 0
, but that's probably just a matter of taste. I find that version easier to read.
BOOST_CHECK(CWalletDB(dbw).EraseNameFirstUpdate(nameBad)); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bonus points: Can you also add a unit test for the auto-updating logic? That would be even better to have, I think -- but may be complicated to write (I don't know how unit testing in Qt works).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing Qt unit tests is pretty complicated, but it's been on my list for a while now. I tried a while back but couldn't get it to work correctly basing from the existing Qt tests. I'll definitely give it another stab, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. That's certainly not required for merging this IMHO - but if you do find time to work on it later, it would be much appreciated! (And I feel your pain in writing the Qt tests!)
I would prefer to squash the commits if you don't mind -- but I'm also fine with keeping it as it is, if that would be a lot of extra work and complication for you. (Just wanted to point this out for the future.) |
877c11c
to
671de5f
Compare
Thanks for the updates! Please let me know when you are ready for a second round of review - and please note that I'll be busy the next couple of weekends, so I can't promise how much time I'll have for Namecoin-related work. But I should probably also be able to do a follow-up review in a couple of evenings during the week. |
671de5f
to
6b61c8a
Compare
ea6071a
to
6f087a9
Compare
Alright. I've worked through all your comments @domob1812 and made lots of improvements. Your review comments were extremely helpful, so thanks for going through everything. Let me know if you get a chance to go through my revisions. One thing I noticed is that the first test (https://travis-ci.org/namecoin/namecoin-core/jobs/295544697) seems to always fail in Travis, but it succeeds local. Something about not being able to find certain Namecoin commands? I've fixed all the other test issues, though. Maybe @JeremyRand knows more about this? |
Thanks, I'll take another look - although I won't have time until next Monday to do so, unfortunately. In the meantime, @JeremyRand and others: feel free to take a look also, and to test. |
54b6090
to
9f21369
Compare
I replaced the JSON serialization with a more standard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a few more comments, but now everything are just minor things - no bigger refactorings as last time. Thanks for all your work on this!
(But note again that I've not reviewed the Qt-specific stuff too closely, as I don't know much about it anyway. This is particularly true about the .ui files.)
src/names/common.h
Outdated
class CNamePendingData | ||
{ | ||
private: | ||
std::vector<unsigned char> vchToAddress; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use vchType
as elsewhere in the names/* code.
inline const std::string getToAddress() { return ValtypeToString(vchToAddress); } | ||
inline const std::string getHex() { return ValtypeToString(vchHex); } | ||
inline const std::string getRand() { return ValtypeToString(vchRand); } | ||
inline const std::string getData() { return ValtypeToString(vchData); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand the code correctly, you are actually storing the address in its string representation in the vchType
. Similarly for hex and rand, which are stored as hex strings, right?
I think since you have this wrapper class and already need to convert between string
and vchType
, you should actually encode the data properly: The address can be a CScript
, and hex/rand can be the actual binary data in vchType
, not the hex string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm down to this last one before I start doing more testing, but I'm a little confused. Do you want me to not return std::string
and instead return standard internal types like CScript
etc? Or are you saying I can leave it accepting/returning std::string
but encode internally and serialize to the reference types (CScript
, etc)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got it working the first way, accepting/returning std::string
but serializing toAddress, txid, rand to CScript
, uint256
, uint160
respectively. If you had something different in mind, let me know. For the way the UI code is using the wallet, it's easier for me to just use strings and it allows me to not have to mess with internal types in the Qt code. But I can change if required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Yes, that's exactly what I meant - storing and serialising as raw data. Interfacing to the UI as strings is certainly fine.
src/qt/configurenamedialog.h
Outdated
|
||
explicit ConfigureNameDialog(const PlatformStyle *platformStyle, | ||
const QString &_name, const QString &data, | ||
bool _firstUpdate, QWidget *parent = 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: nullptr
instead of 0
.
void on_pasteButton_clicked(); | ||
|
||
private: | ||
Ui::ConfigureNameDialog *ui; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
src/qt/configurenamedialog.h
Outdated
QString returnTransferTo; | ||
WalletModel *walletModel; | ||
QString name; | ||
bool firstUpdate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think a couple of these variables can actually be const
(e. g., firstUpdate
).
src/qt/walletmodel.cpp
Outdated
|
||
std::vector<std::reference_wrapper<std::string>> WalletModel::sendPendingNameFirstUpdates() | ||
{ | ||
std::vector<std::reference_wrapper<std::string>> successfulNames; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need a reference_wrapper<string>
here? I think just having a vector<string>
would make the code simpler and easier to read, besides avoiding any potential issues with references to strings that go out of scope. Of course, a vector of references is smaller and faster, but is that really important here vs code simplicity and clarity?
src/qt/walletmodel.cpp
Outdated
const int confirms = val.get_int (); | ||
LogPrintf ("Pending Name FirstUpdate Confirms: %d\n", confirms); | ||
|
||
if ((unsigned int)confirms < MIN_FIRSTUPDATE_DEPTH) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Prefer static_cast
over C-style casts.
src/qt/walletmodel.cpp
Outdated
completedResult = this->completePendingNameFirstUpdate(name, rand, txid, data, toaddress); | ||
|
||
// Locks wallet | ||
unlock_ctx.reset(nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just reset()
without passing nullptr
.
src/wallet/wallet.cpp
Outdated
LOCK(cs_wallet); | ||
std::map<std::string, CNamePendingData> pn = namePendingMap; | ||
std::map<std::string, CNamePendingData>::iterator it = pn.find(name); | ||
return it->second; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can your caller know if the name was not found? (Since namePendingMap.end()
is presumably private, if you have this access function defined.)
src/wallet/walletdb.cpp
Outdated
@@ -17,6 +18,7 @@ | |||
#include "wallet/wallet.h" | |||
|
|||
#include <atomic> | |||
#include <univalue.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what do you need this?
9ad7ae2
to
2f7d103
Compare
@JeremyRand Yes that's fine with me, and sounds indeed like a useful start. |
Based on namecoin#187 by Brandon Roberts. TODO: Untested.
@domob1812 Does the internal |
I'm not entirely sure, but from a quick look it seems that the main thing you need is passing a |
Based on namecoin#187 by Brandon Roberts. TODO: Untested.
Based on namecoin#187 by Brandon Roberts. TODO: Untested.
Based on namecoin#187 by Brandon Roberts. TODO: Untested.
Based on namecoin#187 by Brandon Roberts. TODO: Untested.
Based on namecoin#187 by Brandon Roberts.
Depends on #353 and #373, do not merge this until those are merged and this PR is rebased. TODO: Untested. Based on namecoin#187 by Brandon Roberts.
Based on namecoin#187 by Brandon Roberts.
Depends on #353, do not merge this until that PR is merged and this PR is rebased. Based on namecoin#187 by Brandon Roberts.
Depends on #353, do not merge this until that PR is merged and this PR is rebased. Fixes namecoin#377 Based on namecoin#187 by Brandon Roberts.
Fixes namecoin#129 Based on namecoin#187 by Brandon Roberts.
Fixes namecoin#129 Based on namecoin#187 by Brandon Roberts.
Depends on #353, do not merge this until that PR is merged and this PR is rebased. Fixes namecoin#377 Based on namecoin#187 by Brandon Roberts.
Depends on #353, do not merge this until that PR is merged and this PR is rebased. Fixes namecoin#377 Based on namecoin#187 by Brandon Roberts.
Fixes namecoin#377 Based on namecoin#187 by Brandon Roberts.
@domob1812 We are almost at the 1 week mark here. Things were unexpectedly productive: not only did we get the name_list GUI merged, but the name renewal GUI is ready for review too. If a 2nd week of dev on this front is approved, I plan to focus on the Renew Name button (should be easy), the name_update GUI, and perhaps porting some UX improvements from Electrum-NMC (e.g. friendlier representations of names), and maybe fix the GUI bugs that currently occur with non-ASCII names/values (they're currently hidden from the GUI completely). |
Seems fine with me. :) |
Week 1 has completed. Although this was projected to only cover the @domob1812 Is it okay to pay out for Week 1?
@domob1812 Is it okay to authorize funding of Week 2? (Wasn't sure if your previous comment was a yes, figured I should verify rather than assume.) |
@JeremyRand Yes to both. It is fine for me to pay out week 1, and fine to work on week 2 with Handshake funds. |
Fixes namecoin#377 Based on namecoin#187 by Brandon Roberts.
@domob1812 Is there any convenience function that takes a |
@JeremyRand I don't think there is such a function, but there are a couple of places that iterate over the I think instead of an iterable, you should return |
@domob1812 We are nearing the end of Week 2. Here's what's been accomplished:
Also threw in a few Cirrus failure bug reports and a few Gitian-related fixes, which were getting in my way. Also threw in a Gitian build of If a 3rd week of funding is approved, I will probably focus on finishing up the DNS builder dialog and the namespace-specific name_list GUI functionality, and maybe adding GUI support for non-ASCII names/values. |
@domob1812 Week 2 has been completed. Is it okay to pay out for Week 2?
@domob1812 Is it okay to allocate Handshake funds for Week 3? |
Sounds good to me. Will week 3 wrap it all up, or will then there still be something outstanding that we should work on? |
befa241 Namecoin / Qt: Add name_firstupdate GUI (Jeremy Rand) Pull request description: This PR adds a GUI for `name_firstupdate`, based on Brandon's port of Mikhail's GUI. AFAICT, once #436 is merged, patching this GUI to use `name_autoregister` instead should be roughly a one-liner. Until then, it's still a UX improvement over the status quo, even though the user needs to run `name_new` themselves. Refs #187 ACKs for top commit: domob1812: ACK befa241. Tree-SHA512: 044e2daf0b67992013703fe3e4e6fe255585fa0268b5b084a92c6eff0027f662891adb9633b1a4c1fef7a39de2e796b8aa713b0f901558ce016a00318e5b602a
I've finally completed the merge to namecoin-core/master. I had to refactor several things, due to upstream changed in the internal APIs, so there may be some bugs that didn't exist in the previous version. I also fixed the following bugs:
I know domob said he had some stylistic critiques, so I'd like to work through some of those as well once I know what they are.