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 parsing correct format in btccheckpoint #102

Merged
merged 3 commits into from
Aug 24, 2022

Conversation

KonradStaniec
Copy link
Collaborator

@KonradStaniec KonradStaniec commented Aug 22, 2022

  • Add parsing op return data in btccheckpoint according to format defined in txformatter (i.e requiring headers and proper linking)
  • add tools necessary to generate proper btc transactions (first step toward fuzzing). It was necessary as there are no valid babylon opreturns on any btc chain, therefore we need to generate our own txs for testing.

@KonradStaniec KonradStaniec marked this pull request as ready for review August 22, 2022 16:41
Copy link
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, you put a lot of effort in it! Looks like I missed the previous PR that added the formatter :-/

I only submitted comments where it wasn't obvious what the code was going to do when I first saw it. Maybe some extra comments will help future readers.

Comment on lines +362 to +363
// TODO take from config
chaincfg.MainNetParams.PowLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, it's almost configurable now! 🏁 @SebastianElvis tests already fail with this error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep making this thingy configurable is next in line :)

lowFee = btcutil.Amount(1)
)

func standardCoinbaseScript(blockHeight int32, extraNonce uint64) ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a link for why this is the standard? What is extra nonce?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this the the thing which btcd use when adding coinbase transaction during mining (without the btcd specific coinbase flag CoinbaseFlags = "/P2SH/btcd/"). I will add comment from code base which look like:

// standardCoinbaseScript returns a standard script suitable for use as the
// signature script of the coinbase transaction of a new block.  In particular,
// it starts with the block height that is required by version 2 blocks

Not sure though what the extra nonce is necessary for.

Comment on lines 33 to 34
// opReturnScript returns a provably-pruneable OP_RETURN script with the
// provided data.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean to be provably pruneable?

Copy link
Collaborator Author

@KonradStaniec KonradStaniec Aug 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is how, op_return which will not pollute unspent transaction outputs set, should look like.

return script
}

func solveBlock(header *wire.BlockHeader) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method could do with a short docstring. What does it mean to solve a block, and what does the return value mean? Only after reading it fully did I see that it modifies the input.

Comment on lines +155 to +157
// TODO this will be deterministic without seed but for now it is not that
// important
idx := rand.Uint32()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean non-deterministic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually deterministic, as if we do not call rand.Seed(time.now) or something similar then it will always return the same random number.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I learn something new every day about Go :)

}

func createSpendTx(spend *spendableOut, fee btcutil.Amount) *wire.MsgTx {
spendTx := wire.NewMsgTx(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 like a magic number. I see in the docs it's a version; maybe it could be moved next to opTrueScript?

Comment on lines +197 to +198
spendTx.AddTxOut(wire.NewTxOut(int64(spend.amount-fee),
opTrueScript))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this achieve exactly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each output need to have some script, and from what I understand this is simplest valid script. We could probably leave it as empty byte array, but that way we closer mirror btc.

Copy link
Member

@SebastianElvis SebastianElvis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, especially the part that makes PoWLimit configurable! Some minor comments and no blocker from my side.

@@ -358,6 +359,8 @@ func NewBabylonApp(
// from some global config
6,
10,
// TODO take from config
chaincfg.MainNetParams.PowLimit,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think making this a module parameter is better? Like EpochInterval in https://github.com/babylonchain/babylon/blob/main/proto/babylon/epoching/v1/params.proto.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh I am on the fence here. There are two things against having it as module param:

  • this is used it btclightclient and btccheckpoint, so i would need to be defined in two modules and kept consisten between them. (or defined in one and shared, not sure this is possible though)
  • we are validating pow before including tx in mempool i.e in ValidateBasic which does not have access to genesis. (or at least I am not aware how to make it aware of genesis)

Taking both into account I was thinking of making this a global configurable constant similar to how addresss prefixes are global constants which are accesible from every place, even from ValidateBasic . Downside of this, that it will always need to corrsedpond to btc light client btc genesis header, but I think I can live with it at this moment.

return script
}

func solveBlock(header *wire.BlockHeader) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we try to solve a block when testing Babylon? 😨

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added docstring that this should be headers with low diff (like from simnet) as otherwise this would take too much time. It necessary as in both btclightclient and btccheckpoint we always validate proof of work of provided headers.

@aakoshh
Copy link
Contributor

aakoshh commented Aug 23, 2022

One thing I wanted to mention but forgot is that this check is no longer correct:

isAncestor, err := m.k.IsAncestor(ctx, &fh, &sh)

Originally when we wanted the two transactions to be connected via UTxO, it made sense that there's the first part, spent into the second, so the block the first one is in must be an ancestor of the second, for them to always be finalized together.

Now, however, we don't need this linking, the transactions can go in any order into BTC, as long as they are on the same fork. Say the 1st half has too low fee and only the 2nd half gets included in the ledger. Maybe then the submitter will do it again with a different transaction, same content, but later.

So the correct check is now isAncestor(first, second) || isAncestor(second, first).

@KonradStaniec
Copy link
Collaborator Author

Now, however, we don't need this linking, the transactions can go in any order into BTC, as long as they are on the same fork. Say the 1st half has too low fee and only the 2nd half gets included in the ledger. Maybe then the submitter will do it again with a different transaction, same content, but later.

So the correct check is now isAncestor(first, second) || isAncestor(second, first).

Sure makes sense, I will update it to it now.

Although I wonder if we cannot just remove isAncestor and use MainChainDepth for everything. i.e if at least one part if submission is not on main chain, we do not really care on what fork it is, checkpoint will be in unstable state. And when both are on main chain, then everything is fine as they are on the same fork. I will think about it a bit, and update it if necessary in next pr.

@KonradStaniec KonradStaniec merged commit feab466 into main Aug 24, 2022
@KonradStaniec KonradStaniec deleted the use-correct-format-in-btccheckpoint branch August 24, 2022 16:17
@aakoshh
Copy link
Contributor

aakoshh commented Aug 25, 2022

That sounds correct as well. At least if they are on different forks, they can't both have valid results from the main chain depth method 👍

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