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

BFT Block Puller: BFTDeliverer #4365

Merged
merged 2 commits into from
Nov 15, 2023
Merged

Conversation

tock-ibm
Copy link
Contributor

@tock-ibm tock-ibm commented Aug 15, 2023

Type of change

  • New feature

Description

  • A BFTDeliverer that fetches blocks using a block receiver and maintains a BFTCensorshipMonitor.
  • Abstract the creation of a BFTCensorshipMonitor via an abstract factory, so that we can use a mock for it in testing.
  • Add a "ShuffledEndpoints" method to the connection source and test it.
  • Unit testing of BFTDeliverer.

Related issues

#4348

@tock-ibm tock-ibm requested a review from a team as a code owner August 15, 2023 10:18
@tock-ibm tock-ibm force-pushed the bft-bp-bftdeliverer branch 9 times, most recently from 003e98c to 2b6d2da Compare August 21, 2023 04:19
@tock-ibm tock-ibm force-pushed the bft-bp-bftdeliverer branch 3 times, most recently from 5e4a566 to 66878c4 Compare October 3, 2023 07:28
break FetchAndMonitorLoop
default:
d.Logger.Errorf("Unexpected error from CensorshipMonitor, something is critically wrong: %s", errMonitor)
break FetchAndMonitorLoop
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we please not use goto style flow control?

This function is pretty big, we can extract the for loop to a separate function and just use continue.

Copy link
Contributor Author

@tock-ibm tock-ibm Nov 7, 2023

Choose a reason for hiding this comment

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

Not sure what you mean by goto style, these are just break of the for loop. since they are called within a select, they must be labeled. Labeling break of loops is actually recommended....

However, you are correct, this loop is indeed too big, as it does not enter a single screen... so I will break it up and try and make it more readable and simplify the flow control.

}

func (d *BFTDeliverer) refreshSources() {
// select an initial source randomly
d.fetchSources = shuffle(d.Orderers.Endpoints())
d.fetchSources = d.Orderers.ShuffledEndpoints()
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we shuffle each time we refresh an endpoint?

Copy link
Contributor Author

@tock-ibm tock-ibm Nov 7, 2023

Choose a reason for hiding this comment

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

When even a single endpoint is changed, all the endpoints are refreshed, i.e. respective channel is closed. In that case we have a new array of sources, possibly of different length. This only happens following a config TX that actually changes the endpoints, and the first time the bft deliverer is started. That is - it happens very rarely. Following a config TX the raw source slice will be the same in all peers. Therefore, in order to avoid all peers selecting the same orderer as their block source, we have to shuffle the raw sources slice and select from the shuffled slice.

}

d.censorshipMonitor.Stop()
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we start everything just to tear it down? Can't we just stop one censorship monitor?

Copy link
Contributor Author

@tock-ibm tock-ibm Nov 7, 2023

Choose a reason for hiding this comment

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

the d.censorshipMonitor.Stop() at the end of the loop is only called when something "bad" happens, which is recoverable with a retry, that is:

  • block fetch error
  • censorship event

These are hopefully rare events. Therefore, for simplicity, it is easier to close all the header receivers and block receiver, and reassign everything from scratch, rather than to complicate the implementation and

  • close only the block receiver and replace it with a header receive
  • close a header receiver and replace it with a block receiver

Note that the censorship monitor is a collection of header receivers, yet failures in header receivers do not cause a restart of the monitor. Header receiver failures are handled within. This is because eventually, an incorrect orderer (malicious) will be assigned to a header receiver, which should be able to tolerate its behavior and not disrupt the reception of blocks.

BFT header receivers that pull headers from the orderers, and keep the time and number of the last one.
The header receivers verify each block as it arrives.
The header receivers will receive (or ask for) full config blocks - in a later commit.
The header receivers will maintain their own private block verifier (bundle) - in a later commit.

A BFT censorship monitor which periodically compares the progress of headers relative to blocks.
The monitor triggers an alert if a header is ahead of the block stream for more than a certain time.

The BFTDeliverer is only a skeleton

Signed-off-by: Yoav Tock <tock@il.ibm.com>
Change-Id: I5180a98640073b87effb478fd86b6fa7d4df5dee
@tock-ibm tock-ibm force-pushed the bft-bp-bftdeliverer branch 2 times, most recently from 47dcfaa to c945a63 Compare November 8, 2023 07:51
- A BFTDeliverer that fetches blocks and maintains a BFTCensorshipMonitor.
- Abstract the creation of a BFTCensorshipMonitor via an abstract factory, so that we can use a mock for it in testing.
- Add a "shuffledEndpoints" method to the connection source and test it.
- Unit testing of BFTDeliverer.

Signed-off-by: Yoav Tock <tock@il.ibm.com>
Change-Id: Ifead3f9e6c803c4d9fabc63acce11c6da472b88d
@yacovm yacovm merged commit 5b1ac91 into hyperledger:main Nov 15, 2023
14 checks passed
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.

2 participants