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

Merge Signer-indices to master #2414

Merged
merged 60 commits into from
May 24, 2022
Merged

Conversation

zhangchiqing
Copy link
Member

@zhangchiqing zhangchiqing commented May 12, 2022

This PR merges signer indices to master.

What does signer indices do?

Each block header contains a list of signer's identifier in Header.ParentVoteIDs field to indicate who have signed (voted) for this block.

For instance, for a group of 8 nodes: [A,B,C,D,E,F,G,H], if a block is signed by 6 of them, [A,C,D,E,G,H], then Header.ParentVoteIDs could be:

Header.ParentVoteIDs = [
    "0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
    "0xDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
    "0xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
    "0xGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
    "0xHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH",
]

Although it's straightforward, the problem is it could take lots of space. On mainnet, ParentVoteIDs field takes about half size of a block head.

How to optimize?

The idea is that instead of indicating who signed by "name" (their identifier), we indicate by "position" (their index).
Since the full group identities is known, and there is a canonical order for the full identities, we can simply indicate by saying the block is signed by the "first" node, and the "third" node, and ...

Therefore, in our example, we could use 8 bits [1,0,1,1,1,0,1] to indicate a block is signed by A,C,D,E,G,H. Each bit indicates whether a node at that index in the canonical order signed the block. We call these bits - "signer indices". It replaced the Header.ParentVoteIDs field, which is 32 bytes * 6 big, with Header.ParentVoterIndices field, which is only 1 byte big.

zhangchiqing and others added 30 commits March 30, 2022 16:43
* update interface

* remove IdentitiesByIndices

* remove TODO

* address review comments

* [Consensus] SignerIndices Optimization (2/4) (#2101)

* implement IdentitiesByIndices

* convert signer index

* implement encoding and decoding

* add test cases

* remove signer indices file

* fix Packer

* add comments

* remove IdentitiesByIndices

* update mock

* fix test cases

* add comments

* remove fields

* fix ParentVoterIDs

* fix verifier

* fix mock

* implement staking vote progressor

* fix tests

* move to module/packer

* fix tests

* fix validator test

* fix validator test

* use ParentVoterIndices

* add QuorumCertificateWithSignerIDs

* update blockSummary

* move module

* add test cases

* remove comments

* add check to EncodeSignerIndices

* Apply suggestions from code review

Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>

* Apply suggestions from code review

Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>

* Apply suggestions from code review

Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>

* [Consensus] Use SignerIndices in CollectionGuarantee (3/4) (#2140)

* implement IdentitiesByIndices

* implement encoding and decoding

* remove IdentitiesByIndices

* use ParentVoterIndices

* use chainID

* add ChainID

* fix test case

* remove file

* sort assignment to canonical order

* fix guarantee

* fix execution ingestion core

* use signer indices

* add identifierOrder

* use guarantor.FindGuarantors

* fix tests

* fix tests

* fix tests

* disable tests

* fix tests

* fix tests, add validation

* fix fvm test

* fix access tests

* fix tests

* fix tests

* fix select_filter_test tests

* fix access tests

* fix access integration

* fix access integration tests

* revert fvm_test changes

* update fvm_test

* fix exec tests

* fix ingestion engine tests

* fix test cases

* remove todo

* fix error handling

* add comment

* fix tests

* update logging

* refactor

* fix tests

* remove function

* fix error wrapping

* update comment

* update tests

* remove unverified signature

* revert mutator tests change

* update comment

* address comments

* add tests

* add check in NewClusterList to ensure the assignments are sorted in
canonical order

* rename method

* consensus ingestion core log signer indices

* remove tests log

* refactor canonical order check

* replace order.ByNodeIDAsc with order.Canonical

* [Consensus] Refactor for guarantee signer indices (4/4) (#2204)

* wip

* wip

* starting to fix tests

* adding tests

* happy path test

* Added toDo for fixing tests for unhappy paths

* • fixed packer tests
• consolidated logic for checking the padded bits

* re-gen mocks

* fix validPadding

* fix findguarantors

* refactor ingestion/core.go

* move FindGuarantors to protocol

* remove commented code

* fix name

* fix tests

* small refactor

* fix import

* Apply suggestions from code review

Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>

* fix error type

* fix type

* fix error message

* update comments

* update comment

* update tests

* fix identity_test

* fix tests

* fix unittest

* fix cluster tests

* fix tests

* fixtures ingestion engine tests

* fix execution_test

* fix consensus inclusion tests

* fix bootstrap constraint check

* fix cycle dep from NewClusterList (#2225)

Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>
Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>

Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>
Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>

Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>
Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>

Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>
Co-authored-by: Alexander Hentschel <alex.hentschel@axiomzen.co>
@zhangchiqing zhangchiqing marked this pull request as ready for review May 12, 2022 22:45
@github-actions
Copy link
Contributor

github-actions bot commented May 12, 2022

FVM Benchstat comparison

This branch with compared with the base branch onflow:master commit 2e8c9af

The command (for i in {1..N}; do go test ./fvm --bench . --tags relic -shuffle=on; done) was used.

Bench tests were run a total of 7 times on each branch.

Collapsed results for better readability

old.txtnew.txt
time/opdelta
RuntimeTransaction/reference_tx-234.3ms ± 0%32.1ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/convert_int_to_string-235.0ms ± 0%33.5ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/convert_int_to_string_and_concatenate_it-237.7ms ± 0%37.3ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_signer_address-236.3ms ± 0%32.3ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_public_account-238.6ms ± 0%36.1ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_account_and_get_balance-2607ms ± 0%600ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_account_and_get_available_balance-2487ms ± 0%526ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_account_and_get_storage_used-248.4ms ± 0%47.4ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_account_and_get_storage_capacity-2461ms ± 0%441ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_signer_vault-243.8ms ± 0%42.4ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/get_signer_receiver-260.7ms ± 0%54.6ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/transfer_tokens-2200ms ± 0%191ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/load_and_save_empty_string_on_signers_address-239.4ms ± 0%40.4ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/load_and_save_long_string_on_signers_address-281.9ms ± 0%83.6ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/create_new_account-21.19s ± 0%1.20s ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/call_empty_contract_function-236.4ms ± 0%36.7ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/emit_event-250.4ms ± 0%50.8ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/borrow_array_from_storage-2114ms ± 0%107ms ± 0%~(p=1.000 n=1+1)
RuntimeTransaction/copy_array_from_storage-2116ms ± 0%108ms ± 0%~(p=1.000 n=1+1)
 
computationdelta
RuntimeTransaction/reference_tx-2202 ± 0%202 ± 0%~(all equal)
RuntimeTransaction/convert_int_to_string-2402 ± 0%402 ± 0%~(all equal)
RuntimeTransaction/convert_int_to_string_and_concatenate_it-2502 ± 0%502 ± 0%~(all equal)
RuntimeTransaction/get_signer_address-2302 ± 0%302 ± 0%~(all equal)
RuntimeTransaction/get_public_account-2402 ± 0%402 ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_balance-2802 ± 0%802 ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_available_balance-22.40k ± 0%2.40k ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_storage_used-2402 ± 0%402 ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_storage_capacity-21.10k ± 0%1.10k ± 0%~(all equal)
RuntimeTransaction/get_signer_vault-2402 ± 0%402 ± 0%~(all equal)
RuntimeTransaction/get_signer_receiver-2602 ± 0%602 ± 0%~(all equal)
RuntimeTransaction/transfer_tokens-23.50k ± 0%3.50k ± 0%~(all equal)
RuntimeTransaction/load_and_save_empty_string_on_signers_address-2602 ± 0%602 ± 0%~(all equal)
RuntimeTransaction/load_and_save_long_string_on_signers_address-2602 ± 0%602 ± 0%~(all equal)
RuntimeTransaction/create_new_account-2202 ± 0%202 ± 0%~(all equal)
RuntimeTransaction/call_empty_contract_function-2402 ± 0%402 ± 0%~(all equal)
RuntimeTransaction/emit_event-2602 ± 0%602 ± 0%~(all equal)
RuntimeTransaction/borrow_array_from_storage-22.60k ± 0%2.60k ± 0%~(all equal)
RuntimeTransaction/copy_array_from_storage-22.60k ± 0%2.60k ± 0%~(all equal)
 
interactionsdelta
RuntimeTransaction/reference_tx-246.7k ± 0%46.7k ± 0%~(all equal)
RuntimeTransaction/convert_int_to_string-246.7k ± 0%46.7k ± 0%~(all equal)
RuntimeTransaction/convert_int_to_string_and_concatenate_it-246.7k ± 0%46.7k ± 0%~(all equal)
RuntimeTransaction/get_signer_address-246.7k ± 0%46.7k ± 0%~(all equal)
RuntimeTransaction/get_public_account-246.7k ± 0%46.7k ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_balance-216.8M ± 0%16.8M ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_available_balance-25.33M ± 0%5.33M ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_storage_used-249.5k ± 0%49.5k ± 0%~(all equal)
RuntimeTransaction/get_account_and_get_storage_capacity-25.32M ± 0%5.32M ± 0%~(all equal)
RuntimeTransaction/get_signer_vault-248.0k ± 0%48.0k ± 0%~(all equal)
RuntimeTransaction/get_signer_receiver-248.4k ± 0%48.4k ± 0%~(all equal)
RuntimeTransaction/transfer_tokens-249.1k ± 0%49.1k ± 0%~(all equal)
RuntimeTransaction/load_and_save_empty_string_on_signers_address-250.2k ± 0%50.2k ± 0%~(all equal)
RuntimeTransaction/load_and_save_long_string_on_signers_address-255.2k ± 0%55.2k ± 0%~(all equal)
RuntimeTransaction/create_new_account-28.47M ± 0%8.47M ± 0%~(all equal)
RuntimeTransaction/call_empty_contract_function-246.9k ± 0%46.9k ± 0%~(all equal)
RuntimeTransaction/emit_event-246.9k ± 0%46.9k ± 0%~(all equal)
RuntimeTransaction/borrow_array_from_storage-253.1k ± 0%53.1k ± 0%~(all equal)
RuntimeTransaction/copy_array_from_storage-253.1k ± 0%53.1k ± 0%~(all equal)
 

@codecov-commenter
Copy link

codecov-commenter commented May 12, 2022

Codecov Report

Merging #2414 (c2a44a7) into master (661c8de) will decrease coverage by 0.30%.
The diff coverage is 65.38%.

@@            Coverage Diff             @@
##           master    #2414      +/-   ##
==========================================
- Coverage   56.94%   56.64%   -0.31%     
==========================================
  Files         653      656       +3     
  Lines       60019    60156     +137     
==========================================
- Hits        34180    34075     -105     
- Misses      22913    23146     +233     
- Partials     2926     2935       +9     
Flag Coverage Δ
unittests 56.64% <65.38%> (-0.31%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
cmd/bootstrap/run/block.go 0.00% <0.00%> (ø)
consensus/hotstuff/committee.go 100.00% <ø> (ø)
consensus/hotstuff/committees/cluster_committee.go 52.85% <0.00%> (ø)
...nsensus/hotstuff/committees/consensus_committee.go 67.44% <0.00%> (+1.15%) ⬆️
consensus/hotstuff/committees/metrics_wrapper.go 0.00% <0.00%> (ø)
consensus/hotstuff/committees/static.go 0.00% <0.00%> (ø)
consensus/hotstuff/eventhandler/event_handler.go 70.07% <ø> (-0.11%) ⬇️
...sensus/hotstuff/verification/combined_signer_v2.go 73.33% <ø> (ø)
engine/common/follower/engine.go 58.39% <ø> (-0.31%) ⬇️
engine/common/rpc/convert/convert.go 15.16% <0.00%> (+0.07%) ⬆️
... and 71 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8db1151...c2a44a7. Read the comment docs.

Copy link
Member

@AlexHentschel AlexHentschel left a comment

Choose a reason for hiding this comment

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

First set of comments. Didn't get through the PR entirely.
Mostly stylistic suggestion and typos. The only noteworthy thing is the error handling of the checksum for the signer indices. We are just returning generic errors, which makes it impossible to identify byzantine inputs as such.

I have added the error handling in this PR (targeting your branch) and fixed a few random typos: #2443

model/flow/quorum_certificate.go Show resolved Hide resolved
model/flow/quorum_certificate.go Outdated Show resolved Hide resolved
model/flow/quorum_certificate.go Show resolved Hide resolved
@@ -49,7 +47,7 @@ func UnpackRandomBeaconSig(sigData []byte) (crypto.Signature, error) {
packer := SigDataPacker{}
sig, err := packer.Decode(sigData)
if err != nil {
return nil, fmt.Errorf("could not decode sig data %s: %w", err, model.ErrInvalidFormat)
return nil, NewInvalidFormatErrorf("could not decode sig data: %w", err)
Copy link
Member

@AlexHentschel AlexHentschel May 18, 2022

Choose a reason for hiding this comment

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

The API here seems a bit inconsistent:

  • in method UnpackRandomBeaconSig we return a InvalidFormatError if the decoding fails
  • in method Decode, we directly return the decoder's error

Suggestions:

  • Would be nice to make this a bit more uniform and also return a InvalidFormatError in Decode
  • I feel InvalidFormatError is an expected error during normal operations (indicating byzantine input). Would be great to document this
     \\ During normal operations, the following error are expected:
     \\   * InvalidFormatError is `sigData` is not a valid encoding

// decode into typed data
data, err := p.Decode(sigData)
if err != nil {
return nil, fmt.Errorf("could not decode sig data %s: %w", err, model.ErrInvalidFormat)
return nil, model.NewInvalidFormatErrorf("could not decode sig data %s", err)
Copy link
Member

Choose a reason for hiding this comment

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

would suggest to move the InvalidFormatError into the Decode function for API consistency

module/signature/checksum.go Outdated Show resolved Hide resolved
module/signature/checksum.go Outdated Show resolved Hide resolved
module/signature/checksum.go Outdated Show resolved Hide resolved
module/signature/checksum.go Outdated Show resolved Hide resolved
minor extension of error handling
Copy link
Contributor

@tarakby tarakby left a comment

Choose a reason for hiding this comment

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

Nice work Leo 🏄🏼

@@ -124,13 +106,12 @@ type Packer interface {
// sig is the aggregated signature data.
// Expected error returns during normal operations:
// * none; all errors are symptoms of inconsistent input data or corrupted internal state.
Pack(blockID flow.Identifier, sig *BlockSignatureData) ([]flow.Identifier, []byte, error)
Pack(blockID flow.Identifier, sig *BlockSignatureData) (signerIndices []byte, sigData []byte, err error)
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the format of the returned sigData []byte ? are the 3 signatures concatenated together? It would be clearer to use a struct maybe?

Copy link
Member Author

Choose a reason for hiding this comment

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

This sigData is to be used by the block header, which is also []byte.

The Pack method is supposed to convert the structured data, which is the input argument sig, into serialized bytes.

I was thinking about turning it into a type alias, but this sigData is going to be shared by both consensus and collection, the sigData type structure is actually different: collection has 1 less signature. So I ended up using []byte.

Comment on lines 23 to 24
// - AggregatedStakingSig crypto.Signature,
// - AggregatedRandomBeaconSig crypto.Signature
Copy link
Contributor

Choose a reason for hiding this comment

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

To be consistent with the rest of the code, we should use []byte for aggregated signatures (or update the code to use crypto.Signature)

@@ -0,0 +1,319 @@
package signature
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the tools fo signer indices dealing with staking and beacon signatures are very specific to Hotstuff and could live under consensus/hotstuff/ instead of module/signature.

Copy link
Member Author

@zhangchiqing zhangchiqing May 18, 2022

Choose a reason for hiding this comment

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

You are right. That's what I was doing initially.

Later we realized the signer indices is not used just by consensus algorithm, but also to encode the approver IDs in the seal, which is not hotstuff related.

If we keep non-beacon related functions in this package to be reused, and move beacon-related functions to consensus/hotstuff, then we would have 2 different places about Encoding/Decoding signer indices, feels a bit having similar logic all over the places.

So in the end, decided to just keep all signer indices related encoding/decoding functions here. It's a trade-off.

Comment on lines 308 to 314
if l == 0 {
return nil
}
// the above check has ensured that lastByte does exist
lastByte := bitVector[l-1]
numPaddedBits := 8*l - numUsedBits
if (lastByte << (8 - numPaddedBits)) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be equivalent and faster ( I haven't run the tests):

Suggested change
if l == 0 {
return nil
}
// the above check has ensured that lastByte does exist
lastByte := bitVector[l-1]
numPaddedBits := 8*l - numUsedBits
if (lastByte << (8 - numPaddedBits)) != 0 {
if numUsedBits & 7 == 0 { // if numUsedBits is multiple of 8, then there are no padding bits to check
return nil
}
// the above check has ensured that lastByte does exist (l==0 is excluded)
lastByte := bitVector[l-1]
if (lastByte << (numUsedBits & 7)) != 0 { // shift by numUsedBits % 8

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea. I verified with some tests, it is correct

Copy link
Member

@AlexHentschel AlexHentschel left a comment

Choose a reason for hiding this comment

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

Very nice. Lots of great documentation and tests. Thanks 👏

Mostly stylistic comments; though there are a few things that might need fixing (marked with ❗).

Comment on lines 299 to 302
// * The number of padded bits are: `numPaddedBits := 8*len(bitVector) - len(canonicalIdentifiers)`
// * We know that numPaddedBits < 8; as `bitVector` passed check 1. Therefore, all padded bits are
// located in `bitVector`s _last byte_.
// * Let `lastByte` be the last byte of `bitVector`. The leading bits, specifically `(8 - numPaddedBits)`
Copy link
Member

Choose a reason for hiding this comment

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

Tarak's optimization yields the same result as the previous code, but a logic is structured slightly differently. Hence, I would suggest to also update the documentation that describes the algorithm:

Suggested change
// * The number of padded bits are: `numPaddedBits := 8*len(bitVector) - len(canonicalIdentifiers)`
// * We know that numPaddedBits < 8; as `bitVector` passed check 1. Therefore, all padded bits are
// located in `bitVector`s _last byte_.
// * Let `lastByte` be the last byte of `bitVector`. The leading bits, specifically `(8 - numPaddedBits)`
// * As `bitVector` passed check 1, all padded bits are located in `bitVector`s _last byte_.
// * Let `lastByte` be the last byte of `bitVector`. The leading bits, specifically `numUsedBits & 7`,


signers, err := signature.DecodeSignerIndicesToIdentities(allParticipants, qc.SignerIndices)
if err != nil {
if errors.Is(err, signature.ErrIllegallyPaddedBitVector) || errors.Is(err, signature.ErrIncompatibleBitVectorLength) {
Copy link
Member

Choose a reason for hiding this comment

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


sorry, forgot to add this in my PR: we also need check for ErrInvalidChecksum here:

Suggested change
if errors.Is(err, signature.ErrIllegallyPaddedBitVector) || errors.Is(err, signature.ErrIncompatibleBitVectorLength) {
if errors.Is(err, signature.ErrIllegallyPaddedBitVector) || errors.Is(err, signature.ErrIncompatibleBitVectorLength) || errors.Is(err, signature.ErrInvalidChecksum) {

}
if err != nil {
return fmt.Errorf("internal error retrieving collector clusters: %w", err)

Copy link
Member

Choose a reason for hiding this comment

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

In my mind, this is all one code block, because the error checks all pertain to the ClusterByChainID call above.
I personally find Go already quite verbose and prefer not to add unnecessary newlines 😅

Suggested change

cluster, _, ok := clusters.ByNodeID(guarantors[0])
if !ok {
return engine.NewInvalidInputErrorf("guarantor (id=%s) does not exist in any cluster", guarantors[0])

Copy link
Member

Choose a reason for hiding this comment

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

same here

Suggested change

}
clusterMembers := cluster.Members()

// TODO: validate checksum
Copy link
Member

Choose a reason for hiding this comment

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

Is this TODO still applicable? I think we already validate the checksum:
DecodeSignerIndicesToIdentifiers calls CompareAndExtract which validates the checkum (?)

Suggested change
// TODO: validate checksum

@@ -69,3 +70,26 @@ func IsSporkRootSnapshot(snapshot Snapshot) (bool, error) {
}
return true, nil
}

// FindGuarantors decodes the signer indices from the guarantee, and finds the guarantor identifiers from protocol state
func FindGuarantors(state State, guarantee *flow.CollectionGuarantee) ([]flow.Identifier, error) {
Copy link
Member

Choose a reason for hiding this comment

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

would be good to document expected error returns here:

Suggested change
func FindGuarantors(state State, guarantee *flow.CollectionGuarantee) ([]flow.Identifier, error) {
// Expected Error returns during normal operations:
// * signature.ErrIncompatibleBitVectorLength indicates that `signerIndices` has the wrong length
// * signature.ErrIllegallyPaddedBitVector is the vector is padded with bits other than 0
// * signature.ErrInvalidChecksum if the input is shorter than the expected checksum contained therein
func FindGuarantors(state State, guarantee *flow.CollectionGuarantee) ([]flow.Identifier, error) {

@@ -996,8 +996,12 @@ func (e *Engine) matchOrRequestCollections(
Hex("collection_id", logging.ID(guarantee.ID())).
Msg("requesting collection")

guarantors, err := protocol.FindGuarantors(e.state, guarantee)
Copy link
Member

Choose a reason for hiding this comment

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

@m4ksio does this function differentiate between byzantine inputs and unexpected internal errors already? If so, we would need proper error treatment here.

"github.com/onflow/flow-go/model/flow/order"
)

// FromIdentifierLists creates assignmentlist with canonical ordering from a list of IdentifierList.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// FromIdentifierLists creates assignmentlist with canonical ordering from a list of IdentifierList.
// FromIdentifierLists creates a `flow.AssignmentList` with canonical ordering from
// the given `identifierLists`.

@@ -28,3 +24,20 @@ func ByReferenceOrder(nodeIDs []flow.Identifier) func(*flow.Identity, *flow.Iden
return indices[identity1.NodeID] < indices[identity2.NodeID]
}
}

func IdentityListCanonical(identities flow.IdentityList) bool {
Copy link
Member

Choose a reason for hiding this comment

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

a minimal goDoc would be great. 🙏 🙇

"github.com/onflow/flow-go/model/flow"
)

func FilterByIndices(identities flow.IdentityList, indices []int) (flow.IdentityList, error) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this function is used at all. Can we remove it?

@zhangchiqing zhangchiqing force-pushed the leo/feature-signer-indices-to-master branch from b659980 to eb26b6c Compare May 19, 2022 22:34
@zhangchiqing
Copy link
Member Author

bors merge

@bors
Copy link
Contributor

bors bot commented May 24, 2022

Build succeeded:

@bors bors bot merged commit 1d6be74 into master May 24, 2022
@bors bors bot deleted the leo/feature-signer-indices-to-master branch May 24, 2022 17:18
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.

4 participants