-
Notifications
You must be signed in to change notification settings - Fork 180
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
sealing halt on exec fork #178
sealing halt on exec fork #178
Conversation
…in business logic
Co-authored-by: Leo Zhang <[email protected]>
model/flow/incorporated_result.go
Outdated
@@ -35,7 +37,14 @@ func NewIncorporatedResult(incorporatedBlockID Identifier, result *ExecutionResu | |||
// ID implements flow.Entity.ID for IncorporatedResult to make it capable of | |||
// being stored directly in mempools and storage. | |||
func (ir *IncorporatedResult) ID() Identifier { |
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.
The IncorporatedResult
is used to store approval signatures when they are received:
flow-go/model/flow/incorporated_result.go
Line 26 in 7c48153
aggregatedSignatures map[uint64]*AggregatedSignature |
aggregatedSignatures
in the ID computation, this changes the ID of the entity, which should not be the case.
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 think it changes the ID of the IncorporatedResult because aggregatedSignatures
is a private field and is ignored in the RLP encoding which is used to calculate the ID
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.
💡 thanks for pointing this out @arrivets . I was not aware that RLP did skip private fields.
Obviously, I didn't read the test you wrote:
flow-go/model/flow/incorporated_result_test.go
Lines 12 to 14 in 49fb4a1
// TestIncorporatedResultID checks that the ID and Checksum of the Incorporated | |
// Result do not depend on the aggregatedSignatures placeholder. | |
func TestIncorporatedResultID(t *testing.T) { |
Rolled back my changes to incorporated_result.go
ejectionCallback OnEjection | ||
limit uint | ||
eject EjectFunc | ||
ejectionCallbacks []mempool.OnEjection |
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.
@zhangchiqing I went back to using a list of ejection callbacks. After trying around a bit, I found this solution to be much more general compared to a single callback. Trying to give a high-level summary here:
- some mempools don't store the entities directly in the backend, but use composite structure, e.g.:
var incResults map[flow.Identifier]*flow.IncorporatedResult - To not expose this internal details to an externally-provided ejection callback, the callback needs to be wrapped before it is injected into the
Backend
. - By allowing the backend to serve multiple callbacks:
- it is trivial for a mempool to wrap any externally-provided callback with the necessary logic before registering the (wrapped) ejection callback with the
Backend
- In contrast, when the
Backend
only accepts a single callback, the situation is much more complex for a mempool that has an internal ejection callback as well as accepts external ejection callbacks (likeIncorporatedResults
): - the mempool must implement a multiplexer which serves its internal mempool as well as an external mempool
- it is trivial for a mempool to wrap any externally-provided callback with the necessary logic before registering the (wrapped) ejection callback with the
To me, it seemed much more straightforward, to include the functionality to serve multiple callbacks into the Backend, specifically so as it is only adds two lines of code here. If you have other ideas, lets sync Leo. I tried for quite some time and this seemed to be by far the easiest (and least error-prone) solution.
} | ||
|
||
// readExecutionForkDetectedFlag attempts to read the flag ExecutionForkDetected from the database. | ||
// In case no value is persisted, the default value is written to the database. |
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 say if no value is persisted, then there is no fork detected? so that we don't need to insert the default value.
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.
👍 implemented
log.Error().Msg("inconsistent seals for the same block") | ||
s.seals.Clear() | ||
s.execForkDetected = true | ||
err := operation.RetryOnConflict(s.db.Update, operation.UpdateExecutionForkDetected(true)) |
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.
Instead of storing a bool value, what about storing the "evidence", which is the two conflicting seals. Because otherwise, we will forget about the evidence after a restart, and only remembered the conclusion without knowing how it leads to it.
We could store the two evidence under the same key codeExecutionForkDetected
. On startup, to check whether we saw conflicting seals before, we could just check if the key exists . if the key exists, then we will log the conflicting seals in the value, and then crash the node.
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.
storing the "evidence"
👍 implemented
if the key exists [...] crash the node.
👍 implemented. For context:
- what we do in case we detect conflicting seals is now encapsulated in
flow-go/module/mempool/consensus/exec_fork_actor.go
Lines 12 to 14 in 33de9d9
type ExecForkActor func([]*flow.IncorporatedResultSeal) func LogForkAndCrash(log zerolog.Logger) ExecForkActor {
@@ -543,6 +542,54 @@ func (bs *BuilderSuite) TestPayloadSealSomeValid() { | |||
bs.Assert().ElementsMatch(bs.chain, bs.assembled.Seals, "should have included only valid chain of seals") | |||
} | |||
|
|||
// TestPayloadSealSomeValidOnFork verifies that builder only includes seals whose |
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.
seems incomplete
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.
thanks for noticing. Fixed the test's doc.
@@ -524,15 +515,23 @@ func (bs *BuilderSuite) TestPayloadSealAllValid() { | |||
bs.Assert().ElementsMatch(bs.chain, bs.assembled.Seals, "should have included valid chain of seals") | |||
} | |||
|
|||
func (bs *BuilderSuite) TestPayloadSealSomeValid() { | |||
// TestPayloadSealSomeValidOnFork verifies that builder only includes seals whose |
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.
seems incomplete
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.
Sorry, this entire test was an outdated artifact from work-in-progress. Removed it
// [first] <- [F0] <- [F1] <- [F2] <- [F3] <- [A0] <- [A1] <- [A2] <- [A3] | ||
// Where block | ||
// * [first] is sealed and finalized | ||
// * [F0] ... [F3] are finalized but _not_ sealed | ||
// * [A0] ... [A3] are _not_ finalized and _not_ sealed | ||
// We now create an additional fork: [F3] <- [B0] <- [B1] <- ... <- [B7] |
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'm not quite clear how this tests work.
But if you need help creating such forks in tests, I have an example here.
https://github.com/onflow/flow-go/blob/master/engine/execution/ingestion/engine_test.go#L816-L831
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.
thanks for the reference. The test for the Builder
already contained its own implementation:
flow-go/module/builder/consensus/builder_test.go
Lines 87 to 92 in addcb4b
// createAndRecordBlock creates a new block chained to the previous block (if it | |
// is not nil). The new block contains a receipt for a result of the previous | |
// block, which is also used to create a seal for the previous block. The seal | |
// and the result are combined in an IncorporatedResultSeal which is a candidate | |
// for the seals mempool. | |
func (bs *BuilderSuite) createAndRecordBlock(parentBlock *flow.Block) *flow.Block { |
it has some specialized functionality for testing the payload
Builder
:
- creates execution receipts and seals for the blocks and includes them into the block's payloads
- tracks the created seals and blocks in the mempool mocks
I am inclined to keep the current test structure as I just added a test. 😅
if err != nil { | ||
return fmt.Errorf("failed to update execution-fork-detected flag: %w", err) | ||
} | ||
return ExecutionForkErr |
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 was looking for a test case that verifies this error will be raised, but didn't find.
There are different ways to test, the simplest would be a unittest that test this function. Or a test that tests the Add
function.
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.
thanks for flagging this. The ExecutionForkErr
is only used internally within ExecForkSuppressor
:
flow-go/module/mempool/consensus/exec_fork_suppressor.go
Lines 136 to 140 in 49fb4a1
err := s.enforceConsistentStateTransitions(newSeal, otherSeal) | |
if errors.Is(err, executionForkErr) { | |
s.onExecFork([]*flow.IncorporatedResultSeal{newSeal, otherSeal}) | |
return false, nil | |
} |
For context:
- When implementing
ExecForkSuppressor
, I decided not to error onAdd
in case a fork is detected. Instead, theExecForkSuppressor
will internally clear the wrapped mempool and drop any subsequent seals which are added. In my view, this provides the following advantage:- The higher-level business logic can be oblivious to the existence of the
ExecForkSuppressor
wrapper. Otherwise, we would have to include additional logic to treat the specific errors from the wrapper (which is only semi-temporary). - Not erroring allows the higher-level business logic to potentially continue (just with halted sealing)
- The higher-level business logic can be oblivious to the existence of the
Thanks for the insightful review comments @zhangchiqing . I have implemented most of your suggestions. Please note that I have split up the logic a bit more:
|
// important to prevent memory leak | ||
newSealID := newSeal.ID() | ||
if _, exists := s.seals.ByID(newSealID); !exists { | ||
return added, 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.
I think it should return false
at this point. But if we've made it this far, added
is true
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.
Totally agree with your thinking and would prefer a different return value in this particular case. Before we decide what the return value should be, lets take a look at the larger picture:
ExecForkSuppressor
is a wrapper a aroundmempool.IncorporatedResultSeals
. So how does the implementation behave when youAdd
an entity and the mempool overflows?mempool.IncorporatedResultSeals
is implemented byflow-go/module/mempool/stdmap/incorporated_result_seals.go
Lines 21 to 24 in d14a1e7
// Add adds an IncorporatedResultSeal to the mempool func (ir *IncorporatedResultSeals) Add(seal *flow.IncorporatedResultSeal) (bool, error) { return ir.Backend.Add(seal), nil } Backend
flow-go/module/mempool/stdmap/backend.go
Lines 131 to 138 in d14a1e7
// Add adds the given item to the pool. func (b *Backend) Add(entity flow.Entity) bool { b.Lock() defer b.Unlock() added := b.Backdata.Add(entity) b.reduce() return added } Backdata
flow-go/module/mempool/stdmap/backend.go
Lines 31 to 40 in d14a1e7
// Add adds the given item to the pool. func (b *Backdata) Add(entity flow.Entity) bool { entityID := entity.ID() _, exists := b.entities[entityID] if exists { return false } b.entities[entityID] = entity return true } - Specifically, the
Backend
always stores the element inBackdata
. The return value indicatesfalse
: entity is already present in the mempool and was deduplicatedtrue
: entity is new from the mempool's perspective and can be added (ignoring mempool's capacity limitations)
- The return value makes no assertion about whether or not an element is subsequently ejected
- Essentially,
IncorporatedResultSeals.Add(seal)
returnstrue
if the entity is addable. Even if the mempool overflows and decides to eject theseal
right away, the seal was still "addable". Note that this convention applies to all mempools backed byBackend
.
ExecForkSuppressor
is only a wrapper, and higher-level business logic should be agnostic to whether or not the wrapper exists. Therefore, I concluded that the wrapper should implement the same convention as the wrapped mempool.
Nevertheless, @arrivets you are raising a valid point:
- Given that a mempool has the ability to eject elements, can we base some algorithmic decisions on the return value?
- If the mempool returns
false
, it is telling us that the entity is already stored. However, this might change any moment, as another routine might concurrently add another entity leading to the ejection of our entity. - Likewise, if the mempool returns
true
, the entity might be ejected right away as well.
model/flow/incorporated_result.go
Outdated
@@ -35,7 +37,14 @@ func NewIncorporatedResult(incorporatedBlockID Identifier, result *ExecutionResu | |||
// ID implements flow.Entity.ID for IncorporatedResult to make it capable of | |||
// being stored directly in mempools and storage. | |||
func (ir *IncorporatedResult) ID() Identifier { |
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 think it changes the ID of the IncorporatedResult because aggregatedSignatures
is a private field and is ignored in the RLP encoding which is used to calculate the ID
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.
Had some optional suggestions. Other than that looks great 👍
|
||
// All returns all the IncorporatedResultSeals in the mempool | ||
func (s *ExecForkSuppressor) All() []*flow.IncorporatedResultSeal { | ||
s.mutex.RLock() |
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.
Do we need to lock? I think seals
itself is concurrent-safe.
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.
Interesting suggestion. 🤔
You are probably right: we don't need to lock for methods that only do an atomic read from the wrapped mempool. But I am not 100% sure.
- We certainly need to lock
ExecForkSuppressor
for modifying operations such asAdd
orRem
as they interact with the wrapped mempool multiple times. - So the question is then: can anything bad happen if we read from the wrapped mempool, while
Add
orRem
are modifying it at the same time?
As long as I am not sure, I am hesitant to remove the lock here. With the lock, we are sure that we don't have any concurrency edge cases.
sealsForBlock map[flow.Identifier]sealSet // map BlockID -> set of IncorporatedResultSeal | ||
execForkDetected bool | ||
onExecFork ExecForkActor |
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.
Optional suggestion:
If we are committing to the approach that we will crash as soon as we detect forks, then we could simply the logic here.
For instance, we could use the default log and crash as the onExecFork
, and execForkDetected
is not need, because we will crash if detected, and if we haven't crashed, then it means we haven't detected execFork yet. And we don't need sealSet
either, because there won't be 3 conflicting seals for the same block. As soon as there are 2 conflicting, then we will log them, restore them as evidence and crash.
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.
Agree, it is complexity we don't utilize at this point and thereby a risk for additional bugs. Though, the code is quite well tested so I feel this risk is relatively low. I still think the benefit of being able to boot up consensus nodes with only halted sealing but otherwise functioning block production outweighs the small risk.
The diff contains: - a lot of changes that concern parts of the library we don't use (other curves a la BN, BLS24-X, BLS12-383 ...), integer protocols (ETRS), field extension machinery ... - otherwise irrelevant changes, e.g. CI/CD - some memory bug fixing [Full Changeset](https://github.com/relic-toolkit/relic/compare/7a9bba7f..9206ae5) **Fixed bugs:** - Unexpected failure of ep2\_mul\[\_lwnaf\] above the prime group order [\onflow#64](relic-toolkit/relic#64) **Closed issues:** - Other way to construct towered extension fields [\onflow#203](relic-toolkit/relic#203) - blake2.h:101:5: error: size of array element is not a multiple of its alignment [\onflow#202](relic-toolkit/relic#202) - ECIES 160bit [\onflow#201](relic-toolkit/relic#201) - Compilation with "ARITH gmp" fails [\onflow#200](relic-toolkit/relic#200) - Support for armv8-a ? [\onflow#198](relic-toolkit/relic#198) - Function name bn\_init conflicts with OpenSSL when used in tandem [\onflow#196](relic-toolkit/relic#196) - 16-bit MSP430 [\onflow#193](relic-toolkit/relic#193) - Modular exponentiation returns 1 if exponent is 0 and modulo is 1 [\onflow#185](relic-toolkit/relic#185) - Compilation of RELIC with bls12-446 and bls12-455 fails [\onflow#182](relic-toolkit/relic#182) - test\_bn fails with BLS12-381 preset [\onflow#181](relic-toolkit/relic#181) - \[BUG\] undefined reference to `bench_init', `bench\_clean' [\onflow#180](relic-toolkit/relic#180) - Tests FTBFS because of missing symbol in header [\onflow#179](relic-toolkit/relic#179) - Builds are broken [\onflow#178](relic-toolkit/relic#178) - compile error inlining failed in call to always\_inline ‘\_mm\_alignr\_epi8’ on unbantu20.04 gcc9 [\onflow#177](relic-toolkit/relic#177) - bn\_write\_str buffer overflow [\onflow#176](relic-toolkit/relic#176) - ECDSA verify succeeds when it should fail [\onflow#175](relic-toolkit/relic#175) - ec\_mul\_gen hangs with curve SECG\_K256 [\onflow#174](relic-toolkit/relic#174) - Wrong square root computation [\onflow#173](relic-toolkit/relic#173) - Out-of-bounds read via bn\_sqr\_basic [\onflow#172](relic-toolkit/relic#172) - OSS-Fuzz integration [\onflow#171](relic-toolkit/relic#171) - Building Relic with Curve NIST\_P256 throws FATAL ERROR in relic\_fp\_prime.c:120 [\onflow#170](relic-toolkit/relic#170) - Compressing \(packing\) a point to binary array does not comply with X9.62 standard [\onflow#169](relic-toolkit/relic#169) - ‘ctx\_t’ {aka ‘struct \_ctx\_t’} has no member named ‘total’ [\onflow#168](relic-toolkit/relic#168) - relic does not work with C++ [\onflow#167](relic-toolkit/relic#167) - Memory leak in ep2\_curve\_init/clean with ALLOC=DYNAMIC [\onflow#166](relic-toolkit/relic#166) - \*\_is\_valid\(\) functions produce false negative for not normalized points [\onflow#147](relic-toolkit/relic#147) - Bench and Test doesnt build [\onflow#122](relic-toolkit/relic#122) **Merged pull requests:** - Add pairing delegation protocols [\onflow#199](relic-toolkit/relic#199) ([dfaranha](https://github.com/dfaranha)) - Fix support for Win64/MSVC targets. [\onflow#197](relic-toolkit/relic#197) ([dfaranha](https://github.com/dfaranha)) - Simplify generator getting for Gt. [\onflow#194](relic-toolkit/relic#194) ([luozejiaqun](https://github.com/luozejiaqun)) - cmake: Always use user defined CFLAGS, not only for release builds [\onflow#187](relic-toolkit/relic#187) ([xdustinface](https://github.com/xdustinface)) - Fix MinGW build [\onflow#186](relic-toolkit/relic#186) ([xdustinface](https://github.com/xdustinface)) - Remove debug printf in bn\_mxp\_slide [\onflow#184](relic-toolkit/relic#184) ([guidovranken](https://github.com/guidovranken)) - Remove ALLOC = STACK to simplify memory allocation. [\onflow#183](relic-toolkit/relic#183) ([dfaranha](https://github.com/dfaranha)) - Update relic\_alloc.h [\onflow#165](relic-toolkit/relic#165) ([aguycalled](https://github.com/aguycalled)) - Add correct support for FreeBSD and NetBSD [\onflow#164](relic-toolkit/relic#164) ([hoffmang9](https://github.com/hoffmang9))
The diff contains: - a lot of changes that concern parts of the library we don't use (other curves a la BN, BLS24-X, BLS12-383 ...), integer protocols (ETRS), field extension machinery ... - otherwise irrelevant changes, e.g. CI/CD - some memory bug fixing [Full Changeset](https://github.com/relic-toolkit/relic/compare/7a9bba7f..9206ae5) **Fixed bugs:** - Unexpected failure of ep2\_mul\[\_lwnaf\] above the prime group order [\onflow#64](relic-toolkit/relic#64) **Closed issues:** - Other way to construct towered extension fields [\onflow#203](relic-toolkit/relic#203) - blake2.h:101:5: error: size of array element is not a multiple of its alignment [\onflow#202](relic-toolkit/relic#202) - ECIES 160bit [\onflow#201](relic-toolkit/relic#201) - Compilation with "ARITH gmp" fails [\onflow#200](relic-toolkit/relic#200) - Support for armv8-a ? [\onflow#198](relic-toolkit/relic#198) - Function name bn\_init conflicts with OpenSSL when used in tandem [\onflow#196](relic-toolkit/relic#196) - 16-bit MSP430 [\onflow#193](relic-toolkit/relic#193) - Modular exponentiation returns 1 if exponent is 0 and modulo is 1 [\onflow#185](relic-toolkit/relic#185) - Compilation of RELIC with bls12-446 and bls12-455 fails [\onflow#182](relic-toolkit/relic#182) - test\_bn fails with BLS12-381 preset [\onflow#181](relic-toolkit/relic#181) - \[BUG\] undefined reference to `bench_init', `bench\_clean' [\onflow#180](relic-toolkit/relic#180) - Tests FTBFS because of missing symbol in header [\onflow#179](relic-toolkit/relic#179) - Builds are broken [\onflow#178](relic-toolkit/relic#178) - compile error inlining failed in call to always\_inline ‘\_mm\_alignr\_epi8’ on unbantu20.04 gcc9 [\onflow#177](relic-toolkit/relic#177) - bn\_write\_str buffer overflow [\onflow#176](relic-toolkit/relic#176) - ECDSA verify succeeds when it should fail [\onflow#175](relic-toolkit/relic#175) - ec\_mul\_gen hangs with curve SECG\_K256 [\onflow#174](relic-toolkit/relic#174) - Wrong square root computation [\onflow#173](relic-toolkit/relic#173) - Out-of-bounds read via bn\_sqr\_basic [\onflow#172](relic-toolkit/relic#172) - OSS-Fuzz integration [\onflow#171](relic-toolkit/relic#171) - Building Relic with Curve NIST\_P256 throws FATAL ERROR in relic\_fp\_prime.c:120 [\onflow#170](relic-toolkit/relic#170) - Compressing \(packing\) a point to binary array does not comply with X9.62 standard [\onflow#169](relic-toolkit/relic#169) - ‘ctx\_t’ {aka ‘struct \_ctx\_t’} has no member named ‘total’ [\onflow#168](relic-toolkit/relic#168) - relic does not work with C++ [\onflow#167](relic-toolkit/relic#167) - Memory leak in ep2\_curve\_init/clean with ALLOC=DYNAMIC [\onflow#166](relic-toolkit/relic#166) - \*\_is\_valid\(\) functions produce false negative for not normalized points [\onflow#147](relic-toolkit/relic#147) - Bench and Test doesnt build [\onflow#122](relic-toolkit/relic#122) **Merged pull requests:** - Add pairing delegation protocols [\onflow#199](relic-toolkit/relic#199) ([dfaranha](https://github.com/dfaranha)) - Fix support for Win64/MSVC targets. [\onflow#197](relic-toolkit/relic#197) ([dfaranha](https://github.com/dfaranha)) - Simplify generator getting for Gt. [\onflow#194](relic-toolkit/relic#194) ([luozejiaqun](https://github.com/luozejiaqun)) - cmake: Always use user defined CFLAGS, not only for release builds [\onflow#187](relic-toolkit/relic#187) ([xdustinface](https://github.com/xdustinface)) - Fix MinGW build [\onflow#186](relic-toolkit/relic#186) ([xdustinface](https://github.com/xdustinface)) - Remove debug printf in bn\_mxp\_slide [\onflow#184](relic-toolkit/relic#184) ([guidovranken](https://github.com/guidovranken)) - Remove ALLOC = STACK to simplify memory allocation. [\onflow#183](relic-toolkit/relic#183) ([dfaranha](https://github.com/dfaranha)) - Update relic\_alloc.h [\onflow#165](relic-toolkit/relic#165) ([aguycalled](https://github.com/aguycalled)) - Add correct support for FreeBSD and NetBSD [\onflow#164](relic-toolkit/relic#164) ([hoffmang9](https://github.com/hoffmang9))
The diff contains: - a lot of changes that concern parts of the library we don't use (other curves a la BN, BLS24-X, BLS12-383 ...), integer protocols (ETRS), field extension machinery ... - otherwise irrelevant changes, e.g. CI/CD - some memory bug fixing [Full Changeset](https://github.com/relic-toolkit/relic/compare/7a9bba7f..9206ae5) **Fixed bugs:** - Unexpected failure of ep2\_mul\[\_lwnaf\] above the prime group order [\onflow#64](relic-toolkit/relic#64) **Closed issues:** - Other way to construct towered extension fields [\onflow#203](relic-toolkit/relic#203) - blake2.h:101:5: error: size of array element is not a multiple of its alignment [\onflow#202](relic-toolkit/relic#202) - ECIES 160bit [\onflow#201](relic-toolkit/relic#201) - Compilation with "ARITH gmp" fails [\onflow#200](relic-toolkit/relic#200) - Support for armv8-a ? [\onflow#198](relic-toolkit/relic#198) - Function name bn\_init conflicts with OpenSSL when used in tandem [\onflow#196](relic-toolkit/relic#196) - 16-bit MSP430 [\onflow#193](relic-toolkit/relic#193) - Modular exponentiation returns 1 if exponent is 0 and modulo is 1 [\onflow#185](relic-toolkit/relic#185) - Compilation of RELIC with bls12-446 and bls12-455 fails [\onflow#182](relic-toolkit/relic#182) - test\_bn fails with BLS12-381 preset [\onflow#181](relic-toolkit/relic#181) - \[BUG\] undefined reference to `bench_init', `bench\_clean' [\onflow#180](relic-toolkit/relic#180) - Tests FTBFS because of missing symbol in header [\onflow#179](relic-toolkit/relic#179) - Builds are broken [\onflow#178](relic-toolkit/relic#178) - compile error inlining failed in call to always\_inline ‘\_mm\_alignr\_epi8’ on unbantu20.04 gcc9 [\onflow#177](relic-toolkit/relic#177) - bn\_write\_str buffer overflow [\onflow#176](relic-toolkit/relic#176) - ECDSA verify succeeds when it should fail [\onflow#175](relic-toolkit/relic#175) - ec\_mul\_gen hangs with curve SECG\_K256 [\onflow#174](relic-toolkit/relic#174) - Wrong square root computation [\onflow#173](relic-toolkit/relic#173) - Out-of-bounds read via bn\_sqr\_basic [\onflow#172](relic-toolkit/relic#172) - OSS-Fuzz integration [\onflow#171](relic-toolkit/relic#171) - Building Relic with Curve NIST\_P256 throws FATAL ERROR in relic\_fp\_prime.c:120 [\onflow#170](relic-toolkit/relic#170) - Compressing \(packing\) a point to binary array does not comply with X9.62 standard [\onflow#169](relic-toolkit/relic#169) - ‘ctx\_t’ {aka ‘struct \_ctx\_t’} has no member named ‘total’ [\onflow#168](relic-toolkit/relic#168) - relic does not work with C++ [\onflow#167](relic-toolkit/relic#167) - Memory leak in ep2\_curve\_init/clean with ALLOC=DYNAMIC [\onflow#166](relic-toolkit/relic#166) - \*\_is\_valid\(\) functions produce false negative for not normalized points [\onflow#147](relic-toolkit/relic#147) - Bench and Test doesnt build [\onflow#122](relic-toolkit/relic#122) **Merged pull requests:** - Add pairing delegation protocols [\onflow#199](relic-toolkit/relic#199) ([dfaranha](https://github.com/dfaranha)) - Fix support for Win64/MSVC targets. [\onflow#197](relic-toolkit/relic#197) ([dfaranha](https://github.com/dfaranha)) - Simplify generator getting for Gt. [\onflow#194](relic-toolkit/relic#194) ([luozejiaqun](https://github.com/luozejiaqun)) - cmake: Always use user defined CFLAGS, not only for release builds [\onflow#187](relic-toolkit/relic#187) ([xdustinface](https://github.com/xdustinface)) - Fix MinGW build [\onflow#186](relic-toolkit/relic#186) ([xdustinface](https://github.com/xdustinface)) - Remove debug printf in bn\_mxp\_slide [\onflow#184](relic-toolkit/relic#184) ([guidovranken](https://github.com/guidovranken)) - Remove ALLOC = STACK to simplify memory allocation. [\onflow#183](relic-toolkit/relic#183) ([dfaranha](https://github.com/dfaranha)) - Update relic\_alloc.h [\onflow#165](relic-toolkit/relic#165) ([aguycalled](https://github.com/aguycalled)) - Add correct support for FreeBSD and NetBSD [\onflow#164](relic-toolkit/relic#164) ([hoffmang9](https://github.com/hoffmang9))
The diff contains: - a lot of changes that concern parts of the library we don't use (other curves a la BN, BLS24-X, BLS12-383 ...), integer protocols (ETRS), field extension machinery ... - otherwise irrelevant changes, e.g. CI/CD - some memory bug fixing [Full Changeset](https://github.com/relic-toolkit/relic/compare/7a9bba7f..9206ae5) **Fixed bugs:** - Unexpected failure of ep2\_mul\[\_lwnaf\] above the prime group order [\onflow#64](relic-toolkit/relic#64) **Closed issues:** - Other way to construct towered extension fields [\onflow#203](relic-toolkit/relic#203) - blake2.h:101:5: error: size of array element is not a multiple of its alignment [\onflow#202](relic-toolkit/relic#202) - ECIES 160bit [\onflow#201](relic-toolkit/relic#201) - Compilation with "ARITH gmp" fails [\onflow#200](relic-toolkit/relic#200) - Support for armv8-a ? [\onflow#198](relic-toolkit/relic#198) - Function name bn\_init conflicts with OpenSSL when used in tandem [\onflow#196](relic-toolkit/relic#196) - 16-bit MSP430 [\onflow#193](relic-toolkit/relic#193) - Modular exponentiation returns 1 if exponent is 0 and modulo is 1 [\onflow#185](relic-toolkit/relic#185) - Compilation of RELIC with bls12-446 and bls12-455 fails [\onflow#182](relic-toolkit/relic#182) - test\_bn fails with BLS12-381 preset [\onflow#181](relic-toolkit/relic#181) - \[BUG\] undefined reference to `bench_init', `bench\_clean' [\onflow#180](relic-toolkit/relic#180) - Tests FTBFS because of missing symbol in header [\onflow#179](relic-toolkit/relic#179) - Builds are broken [\onflow#178](relic-toolkit/relic#178) - compile error inlining failed in call to always\_inline ‘\_mm\_alignr\_epi8’ on unbantu20.04 gcc9 [\onflow#177](relic-toolkit/relic#177) - bn\_write\_str buffer overflow [\onflow#176](relic-toolkit/relic#176) - ECDSA verify succeeds when it should fail [\onflow#175](relic-toolkit/relic#175) - ec\_mul\_gen hangs with curve SECG\_K256 [\onflow#174](relic-toolkit/relic#174) - Wrong square root computation [\onflow#173](relic-toolkit/relic#173) - Out-of-bounds read via bn\_sqr\_basic [\onflow#172](relic-toolkit/relic#172) - OSS-Fuzz integration [\onflow#171](relic-toolkit/relic#171) - Building Relic with Curve NIST\_P256 throws FATAL ERROR in relic\_fp\_prime.c:120 [\onflow#170](relic-toolkit/relic#170) - Compressing \(packing\) a point to binary array does not comply with X9.62 standard [\onflow#169](relic-toolkit/relic#169) - ‘ctx\_t’ {aka ‘struct \_ctx\_t’} has no member named ‘total’ [\onflow#168](relic-toolkit/relic#168) - relic does not work with C++ [\onflow#167](relic-toolkit/relic#167) - Memory leak in ep2\_curve\_init/clean with ALLOC=DYNAMIC [\onflow#166](relic-toolkit/relic#166) - \*\_is\_valid\(\) functions produce false negative for not normalized points [\onflow#147](relic-toolkit/relic#147) - Bench and Test doesnt build [\onflow#122](relic-toolkit/relic#122) **Merged pull requests:** - Add pairing delegation protocols [\onflow#199](relic-toolkit/relic#199) ([dfaranha](https://github.com/dfaranha)) - Fix support for Win64/MSVC targets. [\onflow#197](relic-toolkit/relic#197) ([dfaranha](https://github.com/dfaranha)) - Simplify generator getting for Gt. [\onflow#194](relic-toolkit/relic#194) ([luozejiaqun](https://github.com/luozejiaqun)) - cmake: Always use user defined CFLAGS, not only for release builds [\onflow#187](relic-toolkit/relic#187) ([xdustinface](https://github.com/xdustinface)) - Fix MinGW build [\onflow#186](relic-toolkit/relic#186) ([xdustinface](https://github.com/xdustinface)) - Remove debug printf in bn\_mxp\_slide [\onflow#184](relic-toolkit/relic#184) ([guidovranken](https://github.com/guidovranken)) - Remove ALLOC = STACK to simplify memory allocation. [\onflow#183](relic-toolkit/relic#183) ([dfaranha](https://github.com/dfaranha)) - Update relic\_alloc.h [\onflow#165](relic-toolkit/relic#165) ([aguycalled](https://github.com/aguycalled)) - Add correct support for FreeBSD and NetBSD [\onflow#164](relic-toolkit/relic#164) ([hoffmang9](https://github.com/hoffmang9))
The diff contains: - a lot of changes that concern parts of the library we don't use (other curves a la BN, BLS24-X, BLS12-383 ...), integer protocols (ETRS), field extension machinery ... - otherwise irrelevant changes, e.g. CI/CD - some memory bug fixing [Full Changeset](https://github.com/relic-toolkit/relic/compare/7a9bba7f..9206ae5) **Fixed bugs:** - Unexpected failure of ep2\_mul\[\_lwnaf\] above the prime group order [\onflow#64](relic-toolkit/relic#64) **Closed issues:** - Other way to construct towered extension fields [\onflow#203](relic-toolkit/relic#203) - blake2.h:101:5: error: size of array element is not a multiple of its alignment [\onflow#202](relic-toolkit/relic#202) - ECIES 160bit [\onflow#201](relic-toolkit/relic#201) - Compilation with "ARITH gmp" fails [\onflow#200](relic-toolkit/relic#200) - Support for armv8-a ? [\onflow#198](relic-toolkit/relic#198) - Function name bn\_init conflicts with OpenSSL when used in tandem [\onflow#196](relic-toolkit/relic#196) - 16-bit MSP430 [\onflow#193](relic-toolkit/relic#193) - Modular exponentiation returns 1 if exponent is 0 and modulo is 1 [\onflow#185](relic-toolkit/relic#185) - Compilation of RELIC with bls12-446 and bls12-455 fails [\onflow#182](relic-toolkit/relic#182) - test\_bn fails with BLS12-381 preset [\onflow#181](relic-toolkit/relic#181) - \[BUG\] undefined reference to `bench_init', `bench\_clean' [\onflow#180](relic-toolkit/relic#180) - Tests FTBFS because of missing symbol in header [\onflow#179](relic-toolkit/relic#179) - Builds are broken [\onflow#178](relic-toolkit/relic#178) - compile error inlining failed in call to always\_inline ‘\_mm\_alignr\_epi8’ on unbantu20.04 gcc9 [\onflow#177](relic-toolkit/relic#177) - bn\_write\_str buffer overflow [\onflow#176](relic-toolkit/relic#176) - ECDSA verify succeeds when it should fail [\onflow#175](relic-toolkit/relic#175) - ec\_mul\_gen hangs with curve SECG\_K256 [\onflow#174](relic-toolkit/relic#174) - Wrong square root computation [\onflow#173](relic-toolkit/relic#173) - Out-of-bounds read via bn\_sqr\_basic [\onflow#172](relic-toolkit/relic#172) - OSS-Fuzz integration [\onflow#171](relic-toolkit/relic#171) - Building Relic with Curve NIST\_P256 throws FATAL ERROR in relic\_fp\_prime.c:120 [\onflow#170](relic-toolkit/relic#170) - Compressing \(packing\) a point to binary array does not comply with X9.62 standard [\onflow#169](relic-toolkit/relic#169) - ‘ctx\_t’ {aka ‘struct \_ctx\_t’} has no member named ‘total’ [\onflow#168](relic-toolkit/relic#168) - relic does not work with C++ [\onflow#167](relic-toolkit/relic#167) - Memory leak in ep2\_curve\_init/clean with ALLOC=DYNAMIC [\onflow#166](relic-toolkit/relic#166) - \*\_is\_valid\(\) functions produce false negative for not normalized points [\onflow#147](relic-toolkit/relic#147) - Bench and Test doesnt build [\onflow#122](relic-toolkit/relic#122) **Merged pull requests:** - Add pairing delegation protocols [\onflow#199](relic-toolkit/relic#199) ([dfaranha](https://github.com/dfaranha)) - Fix support for Win64/MSVC targets. [\onflow#197](relic-toolkit/relic#197) ([dfaranha](https://github.com/dfaranha)) - Simplify generator getting for Gt. [\onflow#194](relic-toolkit/relic#194) ([luozejiaqun](https://github.com/luozejiaqun)) - cmake: Always use user defined CFLAGS, not only for release builds [\onflow#187](relic-toolkit/relic#187) ([xdustinface](https://github.com/xdustinface)) - Fix MinGW build [\onflow#186](relic-toolkit/relic#186) ([xdustinface](https://github.com/xdustinface)) - Remove debug printf in bn\_mxp\_slide [\onflow#184](relic-toolkit/relic#184) ([guidovranken](https://github.com/guidovranken)) - Remove ALLOC = STACK to simplify memory allocation. [\onflow#183](relic-toolkit/relic#183) ([dfaranha](https://github.com/dfaranha)) - Update relic\_alloc.h [\onflow#165](relic-toolkit/relic#165) ([aguycalled](https://github.com/aguycalled)) - Add correct support for FreeBSD and NetBSD [\onflow#164](relic-toolkit/relic#164) ([hoffmang9](https://github.com/hoffmang9))
implements https://github.com/dapperlabs/flow-internal/issues/1294
Goals
The solution in this PR is intended to serve as an additional safety net against verification-sealing bugs:
High-level Implementation Overview
I found it an elegant solution to delegate the logic for detecting execution forks to the
IncorporatedResultSeals
mempool.consensus.Builder
ormatching.Engine
with this somewhat temporary logicIncorporatedResultSeals
interface. The wrapper is completely agnostic of the internal implementationMinor infrastructure revisions contained in this PR
WithBlock(blockID flow.Identifier)
can only be defined once in unittest. This makes it very hard to determine what options are available for the individual fixtures. Naming becomes very convoluted and lengthy.flow-go/cmd/util/cmd/block_hash_by_height_test.go
Line 118 in d61f61f