Skip to content
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

Add package wtxmgr to use walletdb interface #190

Closed
wants to merge 37 commits into from

Conversation

tuxcanfly
Copy link
Contributor

NOTE: This pull request requires #147

Moved txstore to legacy and added package wtxmgr which provides walletdb support.

Legacy txstore will be imported as a part of the wallet setup as implemented in #147.

davecgh and others added 5 commits February 6, 2015 01:08
This commit converts the wallet to use the new secure hierarchical
deterministic wallet address manager package as well as the walletdb
package.

The following is an overview of modified functionality:

- The wallet must now be created before starting the executable
- A new flag --create has been added to create the new wallet using wizard
  style question and answer prompts
- Starting the process without an existing wallet will instruct now
  display a message to run it with --create
- Providing the --create flag with an existing wallet will simply show an
  error and return
Previously a runtime.GC was being invoked which forced it to release the
memory as far as the garbage collector is concerned, but the memory was
not released back to the OS immediatley.  This modification allows the
memory to be released immedately since it won't be needed again until the
next wallet unlock.
@jrick
Copy link
Member

jrick commented Feb 6, 2015

Needs a rebase onto latest intwaddrmgr and some updates for the btcnet -> btcd/chaincfg package move.

@tuxcanfly
Copy link
Contributor Author

Rebased on top of chaincfg move.

@tuxcanfly tuxcanfly force-pushed the wtxmgr branch 2 times, most recently from 528d4cf to 4d3f7e2 Compare February 6, 2015 07:07
Conflicts:
	btcwallet.go
	chain/chain.go
	wallet.go
@jrick
Copy link
Member

jrick commented Feb 6, 2015

These three changes result in the unlinking of all previous txstore history. Instead, I would do it this way:

git mv txstore legacy/txstore # move old txstore to legacy
# rewrite txstore imports to point to legacy so everything continues to build
git commit -a -m "Move txstore package to legacy directory."

# create new wtxmgr package.  Probably easiest to just copy the same files as in your commits.
git add wtxmgr/*
git commit -a -m "Add pkg wtxmgr"

# Rewrite all "legacy/txstore" imports to point to the new wtxmgr package and finish integration.
git commit -a -m "Integrate wtxmgr package."

If done this way, each commit will continue to build (important for bisect) and we still keep all history of how the old txstore package was created by looking at files in the legacy directory (without needing to checkout an older commit).

@davecgh
Copy link
Member

davecgh commented Feb 6, 2015

I agree with @jrick here. That is how I did the waddrmgr as well.

@tuxcanfly
Copy link
Contributor Author

Thanks, good idea to preserve history, will follow that.

@tuxcanfly tuxcanfly force-pushed the wtxmgr branch 2 times, most recently from 8c5662f to 22a05ff Compare February 6, 2015 18:56
@jrick
Copy link
Member

jrick commented Feb 6, 2015

I realize this is more of a txstore conversion to wallet db, but one of the changes I want is to remove the block index. We won't have this information available when wallet gains SPV support, but txstore/wtxmgr relies on it for correctness (as a lookup key).

We should either bite the bullet and rip it out now, or do it in a db upgrade later.

@jrick
Copy link
Member

jrick commented Feb 7, 2015

In no particular order:

  • Several cases of unneeded branching for final returns.
// Instead of this:
if err := fn(); err != nil {
    return err
}
return nil

// Prefer this:
return fn()
  • Slices are created based on a size in the metadata and then each index is set by iterating over values in buckets. This can result in an OOB panic if the db is corrupt or an incorrect size was previously added. Use append here instead (or check that no more than n values are read from the bucket).
  • Keep function signatures on a single line, even if they go over some magic number of characters.
  • When incrementing counts in the metadata, use n+1 (a temporary) at the call site instead of incrementing the variable and writing the new number, if n is not used again later (I haven't yet seen any places where it was).
  • Be cautious with allocations. They can become very expensive, especially in a GC'd language. This code currently creates a lot of garbage during serialization and deserialization. I'll work up some better ways to do this if you don't, but it's a good habit to cringe a little each time you know an allocation is happening and find a more efficient way to do the same thing. For this code, the key will be buffer reuse.
  • Documentation (doc.go) needs to be updated (some descriptions are specific to the old txstore).
  • I am in favor of using tools like stringer to automatically produce fmt.Stringer implementations with generated code since it means less boilerplate code to write and maintain (for example, the ErrorCode type could use this).
  • I don't think this DB format makes as much sense in an actual DB as it did when it was all in memory and a single flat file. For example, the one thing that really stands out to me is how every transaction record must be replaced any time any changes are made to it (e.g. adding Debits or Credits, or marking a Credit spent). Not only that, but the Record also includes the entire wire.MsgTx, so there is a lot of unnecessary serialization and I/O going on whenever something changes. I think having a dedicated bucket just for raw transactions is a better solution, and additional details about credits and debits can be stored in another bucket.

I'll continue with the review later but those are some things to get you started on.

@tuxcanfly
Copy link
Contributor Author

Thanks for the detailed points, will work on those and keep them in mind for future.

@davecgh
Copy link
Member

davecgh commented Feb 7, 2015

I agree with all of @jrick's points save the stringer. I do agree that in general using go generate is nice, but that particular tool generates code that I don't consider anywhere near the quality it needs to be. It doesn't follow Go standards at all, and as a result, causes tools like golint to fail. As long as that remains the case, I don't want code from stringer anywhere near our repos.

@tuxcanfly tuxcanfly force-pushed the wtxmgr branch 5 times, most recently from 6cb4a5e to 1bb5f96 Compare February 13, 2015 15:46
* remove unnecessary if err := fn(); err != nil branches
* use n+1, n-1 in arg instead of n++, n--
* handle index out of range due to invalid metadata
* remove unncessary shaHashToBytes
* format err message for deserializeOutPoint
* remove unreachable code in fetchNumBlockTxRecords
* Return nil in place of empty array on err
* update wtxmgr doc.go for txstore to wtxmgr migration
* remove unnecessary valid pointer funcs
* simplify bool serialization
* define serialize funcs before deserialize - outpoint, block
* pass in object ptrs for deserialize funcs - outpoint, block
* order all serialize/deserialize funcs
* style change - func declarations
* txrecord - return out ptr on deserialize
* formatting, %s for err message
@tuxcanfly
Copy link
Contributor Author

@jrick Updated as per yesterday's discussion i.e. buffer reuse + object reuse, docs and style.

Also started with benchmarks for serialization which might be useful soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants