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

110 refactor consensus and validation #112

Merged
merged 5 commits into from
Jul 29, 2017

Conversation

david-julien
Copy link
Contributor

@david-julien david-julien commented Jul 26, 2017

Related Issue

110

Description

  • Write a few sentences describing the overall goal of this PR.
    • Refactoring the validation code.
    • Merged validMinedBlock and validBlock together.
  • List the general components of the application that this PR will affect.
    • Validation file in block chain was integrated into the consensus package.
    • Errors from validation were moved into their own file in the consensus package.
    • CurrentDifficulty and CurrentBlockReward were moved into their own file in the consensus package.

WIKI Updates

Todos

General:

  • Tests
  • Documentation
  • Wiki

Other (links to TODOs in code):

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 69.93% when pulling a5f6df4 on 110-refactor-consensus-and-validation into d630511 on dev.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 69.93% when pulling 3c926a6 on 110-refactor-consensus-and-validation into d630511 on dev.

Copy link
Member

@jordanschalm jordanschalm left a comment

Choose a reason for hiding this comment

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

Couple minor things. Looks good!

// Big2Exp256 is 2^256 respresented as type "math/big"
Big2Exp256 = util.BigExp(2, 256)
)

// Commonly used max values represented as type "math/big"
var (
// MaxUint256 is the maximum uint232 number represented as type "math/big"
Copy link
Member

Choose a reason for hiding this comment

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

MaxUint256 should be 232?

Copy link
Contributor Author

@david-julien david-julien Jul 27, 2017

Choose a reason for hiding this comment

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

yah so here's the thing.... The tests will only pass if the MaxTarget is set to MaxUint256 because of this guy: proof of work in validation.
So I dunno how to be like, if you're in test mode, MaxTarget is equal to MaxUint256, otherwise please use MaxUint232. Cuz MaxUint232 is the max target for v1.

)
// Find the transaction input in the chain (by hash)
var input *blockchain.Transaction
input = bc.GetInputTransaction(t)
Copy link
Member

Choose a reason for hiding this comment

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

can do input := ...

Copy link
Member

@bfbachmann bfbachmann left a comment

Choose a reason for hiding this comment

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

Great job 🏅

}

// Check that time is not greater than current time or equal to 0.
if uint32(gb.Time) == 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Seems like you're just checking if it's 0 here, not whether it's greater than the current time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there's some more complex time checking stuff that @jordanschalm and I were talking about so we just stuck with this simple check for now. I should probably add a TODO though.

return true, ValidBlock
}

// Check that block number is between 0 and max blocks.
Copy link
Member

Choose a reason for hiding this comment

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

I would change this to: "Check that block number is valid" or something similar because "max blocks" isn't really correct terminology here.

return false, BadTarget
}

// Check that time is not greater than current time or equal to 0
Copy link
Member

Choose a reason for hiding this comment

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

Check current time here too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same as above^

@@ -0,0 +1,40 @@
package consensus
Copy link
Member

Choose a reason for hiding this comment

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

I like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm glad you like this bruno 😗😗

@@ -0,0 +1,106 @@
package consensus
Copy link
Member

Choose a reason for hiding this comment

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

I like this too.

@@ -42,13 +41,6 @@ func RestartMiner(bc *blockchain.BlockChain, b *blockchain.Block) {
// TODO: Make Mine take an interface with a callback as an arguement.
func Mine(bc *blockchain.BlockChain, b *blockchain.Block) *MiningResult {
setStart()
if valid, _ := bc.ValidBlock(b); !valid {
Copy link
Member

@bfbachmann bfbachmann Jul 27, 2017

Choose a reason for hiding this comment

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

Why'd you remove this? Are only valid blocks passed to this function?

Copy link
Contributor

Choose a reason for hiding this comment

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

The miner receives blocks from the pool, and the app orchestrates. No need to re-validate 👍

Copy link
Contributor

@chadlagore chadlagore left a comment

Choose a reason for hiding this comment

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

Lookin cool 🕶

// Verify every Transaction in the block.
for _, t := range b.Transactions[1:] {
if valid, code := VerifyTransaction(bc, t); !valid {
log.Errorf("Invalid Transaction, TransactionCode: %d", code)
Copy link
Contributor

Choose a reason for hiding this comment

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

If we want to log every bad transaction, thats cool but we could probably dry it up a bit by putting these logs at the caller.

@@ -42,13 +41,6 @@ func RestartMiner(bc *blockchain.BlockChain, b *blockchain.Block) {
// TODO: Make Mine take an interface with a callback as an arguement.
func Mine(bc *blockchain.BlockChain, b *blockchain.Block) *MiningResult {
setStart()
if valid, _ := bc.ValidBlock(b); !valid {
Copy link
Contributor

Choose a reason for hiding this comment

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

The miner receives blocks from the pool, and the app orchestrates. No need to re-validate 👍

@@ -75,11 +67,11 @@ func TestCloudBase(t *testing.T) {

CloudBase(b, bc, w.Public())
Copy link
Contributor

Choose a reason for hiding this comment

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

Its still difficult for me to appreciate that this function is mutating the block and adding a new transaction to it. Can we rename it sometime? 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hahaha sure I thought I was being clever but it is sort of hard to understand isn't it 😂

// Test if identical transaction already exists in chain.
end := uint32(len(bc.Blocks))
start := t.Input.BlockNumber
if exists, _, _ := bc.ContainsTransaction(t, start, end); exists {
Copy link
Contributor

Choose a reason for hiding this comment

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

I still worry that we have a hole here, but that is out of scope.

See #113.

Copy link
Member

Choose a reason for hiding this comment

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

Yea I was worried that we are only checking the blockchain from the input transaction to the current block, but I guess that makes sense because the earlier of the two double spend transactions could not have come before it's own input transaction. Am I right there?

Copy link
Contributor

@chadlagore chadlagore Jul 27, 2017

Choose a reason for hiding this comment

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

All this ContainsTransaction bit does is check if any transaction in the chain hashes to HashSum(t). It literally asserts HashSum(t) != HashSum(t0) for all intervening transactions.

If Alice has 10 and sends Bob 10 then sends Bob 9.99, I don't think we catch it because the outputs look different and that changes the hashes. We may catch it elsewhere, but I can't see it 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't write this haha so I wasn't trying to fix anything from 113. I think imma leave it as is, as its a re-factor and we'll handle the errors from 113 on another PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah definitely out of scope, ignore us @david-julien 😄

@@ -12,12 +12,25 @@ var (
Big0 = big.NewInt(0)
// Big1 is 1 represented as type "math/big"
Big1 = big.NewInt(1)
// Big2Exp232 is 2^232 respresented as type "math/big"
Copy link
Contributor

Choose a reason for hiding this comment

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

I see how these are slightly convenient, but I probably will avoid using them because they obfuscate the code.

b := big.NewInt(1) + util.BigExp(2, 232) 👈 pretty clear what I'm doing
b := Big1 + Big2Exp232 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its not just for clarity but it also helps us to avoid allocating new memory for the same values over and over again throughout the code as they are pointers.

BadCloudBase MinedBlockCode = iota
)
// VerifyTransaction tests whether a transaction valid.
func VerifyTransaction(bc *blockchain.BlockChain,
Copy link
Contributor

Choose a reason for hiding this comment

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

This was my silly formatting using PEP8 on my go code from before 🤦‍♂️ . Feel free to undo it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha no I like it! Trying to keep the line length under 80 chars

Copy link
Contributor

Choose a reason for hiding this comment

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

I know the urge 😅

// cumulus. Once the difficulty is dynamic, the target would need to be
// compared to the target calculated for that specific block.
target := blockchain.HashToBigInt(b.Target)
if target.Cmp(c.MaxTarget) == 1 ||
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't this work:

if target.Cmp(blockchain.HashToBigInt(CurrentTarget())) != 0 {
    return false, BadTarget
}

Why would the CurrentTarget() return something out of range?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call! These range checks are code from before the re-factor that I forgot to get rid of. oops 😅

@chadlagore
Copy link
Contributor

Sorry for the merge conflict, happy to see the validation finally move out of the blockchain package!

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 70.718% when pulling 56ffabf on 110-refactor-consensus-and-validation into 5e0015e on dev.

@jordanschalm jordanschalm merged commit 7eee1b7 into dev Jul 29, 2017
@jordanschalm jordanschalm deleted the 110-refactor-consensus-and-validation branch July 29, 2017 19:33
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.

None yet

5 participants