Hi Mike,
Just been looking at the 'dead coinbase resurrection' code in
Wallet#reorganise when it moves dead->pending.
I think it just needs the following:
boolean isDeadCoinbase = t.isCoinBase() &&
dead.containsKey(t.getHash());
if (isDeadCoinbase) {
// There is a dead coinbase tx being received on the best chain.
// Take it out of the dead pool.
// The receive method will then treat it as a new transaction and
put it in spent or unspent as appropriate.
log.info(" coinbaseTX {} <-dead", t.getHashAsString() + ",
confidence = " + t.getConfidence().getConfidenceType().name());
dead.remove(t.getHash());
}
receive(t, b, BlockChain.NewBlockType.BEST_CHAIN, true);
In receive it then gets passed to processTxFromBestChain(tx) where it
gets processed and tx confidence listeners get fired as necessary in
updateForSpend.
The tests all pass with this but, more importantly, it is more logical
as it does not make sense for coinbase tx to ever be pending (They
'existentially' have to be in a block)
Jim.
P.S. Assuming you are happy with this, I will do the comment tidy ups
etc from your review this afternoon/ this evening and prep a commit for
you.
> > Commit: *38c3f88a76f8*
> >
> > Notes:
> > + This commit actually lets the coinbase tx into the wallet. There is a
> > change to Wallet#isTransactionRelevant which previously was filtering them
> > out.
> > + The main test that exercises the 'coinbase death and resurrection'
> > functionality is ChainSplitTests#coinbaseDeath.
> > + I deleted BlockChain#scanTransactions as it was private but not actually
> > being used.
> >
> > tl;dr;
> > You can spend your mining dues!
> >
> >
> > On Monday, June 18, 2012 7:27:40 PM UTC+1, Mike Hearn wrote:
> >>
> >> Yes, I quite agree we can make this more straightforward or safer. The
> >> complexity and fragility of the wallet code is unsatisfying to me.
> >> Unfortunately it's hard to see obvious wins - Bitcoin is just complex.
> >>
> >> On Sat, Jun 16, 2012 at 12:24 PM, Jim <
jim...@fastmail.co.uk> wrote:
> >>
> >>> Hi Mike,
> >>>
> >>> Just having a look at your email about dead coinbase tx processing.
> >>> You are correct, the code is wrong.
> >>> Looking at the CoinSplitTest#coinbaseDeath test, just after the chain
> >>> gets reorged to:
> >>>
> >>> // genesis -> b1 -> b2 -> b3
> >>> // \-> b4 -> b5 -> b6
> >>>
> >>> The status of the dead tx in block b2 is:
> >>> 11:02:49 10 Wallet.**reprocessUnincludedTxAfterReor**g: TX
> >>> b5064848d416ffddfa7f67907bac32**8f5acf2fb7973f110f50803113fa25**1177,
> >>> confidence = DEAD
> >>> 11:02:49 10 Wallet.**reprocessUnincludedTxAfterReor**g: ->inactive
> >>>
> >>> It's confidence is TransactionConfidence.DEAD but it is now in the
> >>> inactive pool. Oh dear!
> >>>
> >>> By cracking open the scope of the Wallet.dead pool from private to
> >>> package level I have added tests that the tx is both
> >>> TransactionConfidence.DEAD and in the dead pool so at least the
> >>> CoinSplitTest#coinbaseDeath fails now i.e. it captures the bug.
> >>>
> >>> It does not feel right being able to put a tx labeled
> >>> TransactionConfidence.DEAD into a pool other than dead so if you can
> >>> suggest improvements here it would be appreciated. Reorgs are
> >>> complicated enough without us trying to bamboozle ourselves with having
> >>> two similar-but-different tx classifications.
> >>>
> >>> I will have a bit more of a look at it today but want to get a MultiBit
> >>> release out early next week so it might have to slip to after that.
> >>>
> >>> Jim
> >>>
> >>>
> >>>
> >>> On Fri, Jun 15, 2012, at 11:17 AM, Mike Hearn wrote:
> >>> > Thanks.
> >>> >
> >>> > I am still confused about the change to reprocessUnincludedTxAfterReor
> >>> **g.
> >>> >
> >>> > During re-org any coinbases that spend to us will be moved to dead ->
> >>> > this
> >>> > is fine.
> >>> >
> >>> > We then process each dead tx and attempt to connect its input -> this
> >>> > will
> >>> > always fail, leading to noSuchTx == numInputs
> >>> >
> >>> > if (noSuchTx == numInputs) the coinbase will be moved back out of dead
> >>> > and
> >>> > into inactive, which is incorrect.
> >>> >
> >>> > Am I wrong?
> >>> >
> >>> > On Thu, Jun 14, 2012 at 8:32 PM, Jim Burton <
jim...@fastmail.co.uk>
> >>> > wrote:
> >>> >
> >>> > > Hi Mike,
> >>> > > I have gone through today's review comments and created a new
> >>> coinbase-tx
> >>> > > commit code accordingly.
> >>> > > It is here:
> >>> > >
> >>> > > Commit: ad2cea535d3e
> >>> > >
> >>> > >
http://code.google.com/r/**jimburton618-bitcoinj-**
> >>> coinbase-tx/source/detail?r=**ad2cea535d3e3d999c34434a327a5d**
> >>> e56812b32f&name=coinbase-**phase3-rebase#<
http://code.google.com/r/jimburton618-bitcoinj-coinbase-tx/source/detail?r=ad2cea535d3e3d999c34434a327a5de56812b32f&name=coinbase-phase3-rebase#>
> >>> > >
> >>> > >
> >>> > >
> >>> > > The only non-obvious change is around the
> >>> > > Wallet#**reprocessUnincludedTxAfterReor**g method.
> >>> > > Changes:
> >>> > > + The coinbase tx are treated just the same as the other tx.
> >>> > > + This code tweak has been deleted:
> >>> > >
> >>> > > - if (input.isCoinBase()) {
> >>> > > - // Input is not in our wallet so there is "no such input tx", bit
> >>> of an
> >>> > > abuse.
> >>> > > - noSuchTx++;
> >>> > > - continue;
> >>> > > - }
> >>> > >
> >>> > > As the coinbase tx are now in the wallet they can be input to other
> >>> txes
> >>> > > in the wallet just like any other - no special casing required.
> >>> > > + Coinbase can appear in reprocessUnincludedTxAfterReor**g so I
> >>> have not put
> >>> > > in a Precondition about them as we discussed via email.
> >>> > >
> >>> > > The tests all run cleanly.
> >>> > >
> >>> > >
> >>> > >
> >>> > >
> >>> > >
> >>> > > On Wednesday, June 13, 2012 5:11:06 PM UTC+1, Mike Hearn wrote:
> >>> > >>
> >>> > >> Thanks Jim!
> >>> > >>
> >>> > >> I posted a review on that changelist.
> >>> > >>
> >>> > >> On Sat, Jun 9, 2012 at 1:31 PM, Jim Burton <
jim...@fastmail.co.uk>
> >>> wrote:
> >>> > >>
> >>> > >>> I have made a commit for the 'coinbase-phase3' work which includes:
> >>> > >>> + checking coinbase tx are spendable in Wallet#completeTx
> >>> > >>> + adding a Transaction#isMature so that you can tell when a tx has
> >>> > >>> matured (i.e coinbase depth > minimum required)
> >>> > >>> + adjusting the wallet balance so that coinbase tx always appear
> >>> in the
> >>> > >>> estimated balance but only appear in the available balance when
> >>> mature.
> >>> > >>> + dealing with coinbase death on reorgs
> >>> > >>>
> >>> > >>> The commit is: *e2718f0c28d9*
> >>> > >>> The changeset is here:
> >>> > >>>
http://code.google.com/r/****jimburton618-bitcoinj-**<
http://code.google.com/r/**jimburton618-bitcoinj-**>
> >>> > >>> coinbase-tx/source/detail?r=****e2718f0c28d972c20f8263db89992f****
> >>> > >>> + BlockChainTest#****coinbaseTransactionAvailibilit****y - checks
> >>> the
> >>> > >>> maturation of coinbase tx and the value of transaction.isMature()
> >>> > >>> + ChainSplitTest#coinbaseDeath - test that coinbase tx get
> >>> > >>> TransactionConfidence.DEAD confidence when moved to a sidechain
> >>> and get
> >>> > >>> TransactionConfidence.BUILDING when they move back to the best
> >>> chain.
> >>> > >>> + WalletTest#****coinbaseTransactionSpend - test that you can
> >>> actually
> >>> > >>> spend a mature coinbase tx and it gets received to a different
> >>> wallet ok
> >>> > >>> + CoinbaseBlockTest#****testReceiveCoinbaseTransaction - test
> >>> that a
> >>> > >>> production coinbase I bought off a miner gets input to a wallet
> >>> correctly.
> >>> > >>> (This was produced in fixing a bug in MultiBit but is a useful
> >>> real world
> >>> > >>> test so I have moved it into bitcoinj)
> >>> > >>>
> >>> > >>> The tests all run ok.
> >>> > >>>
> >>> > >>> Cheers
> >>> > >>>
> >>> > >>>
> >>> > >>> On Friday, June 8, 2012 4:59:32 PM UTC+1, Mike Hearn wrote:
> >>> > >>>>
> >>> > >>>> OK, merged.
> >>> > >>>>
> >>> > >>>> On Thu, Jun 7, 2012 at 6:45 PM, Mike Hearn <
he...@google.com>
> >>> wrote:
> >>> > >>>>
> >>> > >>>>> Yep that's right. It's an API change but not a format change.
> >>> > >>>>> On Jun 7, 2012 5:30 PM, "Jim Burton" <
jim...@fastmail.co.uk>
> >>> wrote:
> >>> > >>>>>
> >>> > >>>>>> In preparation for the coinbase-phase3 patch, I have done a
> >>> commit
> >>> > >>>>>> against master which simply renames TransactionConfidence.****
> >>> OVERRIDD*
> >>> > >>>>>> *EN_BY_DOUBLE_SPEND to
> >>> > >>>>>> TransactionConfidence.DEAD
> >>> > >>>>>>
> >>> > >>>>>> It will make the commit that actually does the work smaller and
> >>> > >>>>>> easier to review if I rebase against a master with the rename
> >>> in.
> >>> > >>>>>> The changeset is here:
> >>> > >>>>>>
> >>> master-with-rename<
http://code.google.com/r/jimburton618-bitcoinj-coinbase-tx/source/detail?r=584141ab0321feebdda54e32fd7fbe8689af99e6&name=bitcoinj-master-with-rename>
> >>> >
> >>> > >>>>>>
> >>> > >>>>>> It is the branch : bitcoinj-master-with-rename
> >>> > >>>>>> commit : 584141ab0321
> >>> > >>>>>>
> >>> > >>>>>> For this commit I just wanted to* double check* a change to
> >>> > >>>>>> bitcoin.proto. I have relabelled the TransactionConfidence.****
> >>> OVERRIDD
> >>> > >>>>>> **EN_BY_DOUBLE_SPEND to DEAD but the enum number *has not*
> >>> changed.
> >>> > >>>>>> I believe this means that any
> >>> > >>>>>> previously stored wallet will load properly.
> >>> > >>>>>>
> >>> > >>>>>> Once that goes in I will rebase against the new master and post
> >>> up a
> >>> > >>>>>> commit for review.
> >>> > >>>>>>
> >>> > >>>>>>
> >>> > >>>>>>
> >>> > >>>>>> On Wednesday, June 6, 2012 10:42:43 AM UTC+1, Mike Hearn wrote:
> >>> > >>>>>>>
> >>> > >>>>>>> Cool, thanks for the update. Sounds like good progress!
> >>> > >>>>>>>
> >>> > >>>>>>> On Tue, Jun 5, 2012 at 9:20 PM, Jim Burton <
> >>>
jim...@fastmail.co.uk>wrote:
> >>> > >>>>>>>
> >>> > >>>>>>>> I have made a bit of progress on the coinbase tx:
> >>> > >>>>>>>>
> >>> > >>>>>>>> 1) The transaction now has a "isMature()" method on indicating
> >>> > >>>>>>>> whether they are spendable yet.
> >>> > >>>>>>>> 2) There is a networkParameters.****
> >>> getSpendable****CoinbaseDepth(**)
> >>> > >>>>>>>> equal to 120 blocks for prodnet, 5 for testnet.
> >>> > >>>>>>>> 3) The wallet balance takes the tx maturity into account. At
> >>> the
> >>> > >>>>>>>> moment an immature tx appears on neither the estimated or
> >>> available
> >>> > >>>>>>>> balance. I think it should probably appear in the estimated
> >>> balance so will
> >>> > >>>>>>>> change that.
> >>> > >>>>>>>> 4) Once the coinbase are mature you can create a spend with
> >>> them.
> >>> > >>>>>>>> (I still need to write a test that they *really* spend).
> >>> > >>>>>>>>
> >>> > >>>>>>>> There is a branch "coinbase-phase3" with Mike's pubkeyscripts
> >>> work
> >>> > >>>>>>>> merged in and the work I have done so far here:
> >>> coinbase-tx/source/list?name=**coinbase-phase3<
http://code.google.com/r/jimburton618-bitcoinj-coinbase-tx/source/list?name=coinbase-phase3>
> >>> >
> >>> > >>>>>>>>
> >>> > >>>>>>>> There is a test BlockChainTest#****testCoinbaseTra******
> >>> nsactionAvailab