-
Notifications
You must be signed in to change notification settings - Fork 962
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
Part 3 of Aligning Beacon Chain with Latest 2.1 - Processing Attestations #423
Part 3 of Aligning Beacon Chain with Latest 2.1 - Processing Attestations #423
Conversation
Codecov Report
@@ Coverage Diff @@
## master #423 +/- ##
==========================================
+ Coverage 73.67% 76.23% +2.55%
==========================================
Files 7 35 +28
Lines 680 2188 +1508
==========================================
+ Hits 501 1668 +1167
- Misses 112 366 +254
- Partials 67 154 +87
Continue to review full report at Codecov.
|
…validate_attestation
… validate_attestation
beacon-chain/blockchain/core.go
Outdated
return signedParentHashes | ||
} | ||
|
||
// getAttestatorIndices returns the attestor committee of based from attestation's shard ID and slot number. |
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.
getAttesterIndices*
beacon-chain/blockchain/core.go
Outdated
|
||
// Get all the block hashes up to cycle length. | ||
parentHashes := b.getSignedParentHashes(block, attestation) | ||
attesterIndices, err := b.getAttestatorIndices(attestation) |
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.
b.getAttesterIndices
😛
beacon-chain/blockchain/core.go
Outdated
lastBit := len(attesterIndices) | ||
if lastBit%8 != 0 { | ||
for i := 0; i < 8-lastBit%8; i++ { | ||
voted, err := utils.CheckBit(attestation.AttesterBitfield, lastBit+i) |
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 we simplify checkBit not to return an error? It seems reasonable that an out of index bit would return false since the bit at that index is not 1. The error seems unecessary IMO and it would make this method easier to use.
beacon-chain/blockchain/service.go
Outdated
@@ -153,6 +153,9 @@ func (c *ChainService) ProcessBlock(block *types.Block) error { | |||
return nil | |||
} | |||
if canProcess { | |||
if err := c.chain.processAttestations(block); err != nil { |
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 branch is untested. Can we add a test to ensure the attestations are processed on a block when canProcess is truthy?
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.
Done. Added TestProcessingBlockWithAttestations
in blockchain's service_test.go
beacon-chain/utils/checkbit_test.go
Outdated
} | ||
for _, tt := range tests { | ||
if BitLength(tt.a) != tt.b { | ||
t.Errorf("Expected %v, Got %v", tt.b, BitLength(tt.b)) |
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 is great use of test driven tests. One improvement you could make is to structure this error message format to include the method name
t.Errorf("BitLength(%d) = %d, want = %d", tt.a, BitLength(tt.a), tt.b)
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.
lgtm
beacon-chain/blockchain/core.go
Outdated
len(attestation.AttesterBitfield), utils.BitLength(len(attesterIndices))) | ||
} | ||
|
||
// Validate attestation can not have non-zero trailing bits. |
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.
/validate/valid/ ??
beacon-chain/blockchain/core.go
Outdated
return nil, fmt.Errorf("can not return attester set of given height, input height %v has to be in between %v and %v", height, sback, sback+params.CycleLength*2) | ||
// getBlockHash returns the block hash of a slot. | ||
func (b *BeaconChain) getBlockHash(slot uint64, block *types.Block) ([]byte, error) { | ||
sback := int(block.SlotNumber()) - params.CycleLength*2 |
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.
What does sback mean?
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.
slot back. getBlockHash
can only return within a range of block.Slot - 128 <= slot < block.Slot
. Let's say current block is 200, but you wanna get the block hash of slot 50. That won't work because the further you can get is 200 - 128. And that is slot back
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.
Will change sback
to slotBack
beacon-chain/blockchain/core.go
Outdated
// getBlockHash returns the block hash of a slot. | ||
func (b *BeaconChain) getBlockHash(slot uint64, block *types.Block) ([]byte, error) { | ||
sback := int(block.SlotNumber()) - params.CycleLength*2 | ||
if !(sback <= int(slot) && int(slot) < sback+params.CycleLength*2) { |
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 change sback+params.CycleLength*2 to int(block.SlotNumber())
beacon-chain/blockchain/core.go
Outdated
// Validate attestation can not have non-zero trailing bits. | ||
lastBit := len(attesterIndices) | ||
if lastBit%8 != 0 { | ||
for i := 0; i < 8-lastBit%8; i++ { |
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 don’t understand this logic. If length is 9, then it would only run check the first bit?
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.
Exactly. Let's say attester_bitfield
is initialized in with attester_bitfield = (len(attestation_indices) + 7) // 8
empty bytes. So if committee_indices size is 10
, attester_bitfield is 2
bytes, but the meaningful bits are still the left 10 bits. This checking from the spec is for keeping the padding bits clean.
beacon-chain/blockchain/service.go
Outdated
@@ -146,13 +146,17 @@ func (c *ChainService) ProcessBlock(block *types.Block) error { | |||
} else { | |||
canProcess, err = c.chain.CanProcessBlock(nil, block, false) | |||
} | |||
fmt.Println(err) |
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.
Remove
Background
The primary load on beacon chain is attestations. To process an attestation means to attest parent block of the beacon chain, or attest block hash of the shard chain. Every beacon node has the responsibility to process all the attestations coming from a beacon block. That's how it calculates active and crystallized state.
Design
This PR implements the
processAttestation
insideprocessBlock
function. Here's todos:hash((slot % CYCLE_LENGTH).to_bytes(8, 'big') + parent_hashes + shard_id + shard_block_hash)