diff --git a/core/assignment.go b/core/assignment.go index ecabb18771..2b1b064dc5 100644 --- a/core/assignment.go +++ b/core/assignment.go @@ -204,15 +204,19 @@ func (c *StdAssignmentCoordinator) ValidateChunkLength(state *OperatorState, blo } num := new(big.Int).Mul(big.NewInt(2*int64(blobLength*percentMultiplier)), minStake) denom := new(big.Int).Mul(big.NewInt(int64(info.ConfirmationThreshold-info.AdversaryThreshold)), totalStake) - maxChunkLength := uint(roundUpDivideBig(num, denom).Uint64()) + maxChunkLength := nextPowerOf2(uint(roundUpDivideBig(num, denom).Uint64())) - maxChunkLength2 := roundUpDivide(2*blobLength*percentMultiplier, MaxRequiredNumChunks*uint(info.ConfirmationThreshold-info.AdversaryThreshold)) - - if maxChunkLength < maxChunkLength2 { - maxChunkLength = maxChunkLength2 + // Ensure that the max chunk length is not greater than the blob length + if maxChunkLength > blobLength { + maxChunkLength = blobLength } - maxChunkLength = uint(nextPowerOf2(uint64(maxChunkLength))) + chunkLengthForMaxRequiredNumChunks := nextPowerOf2(roundUpDivide(2*blobLength*percentMultiplier, MaxRequiredNumChunks*uint(info.ConfirmationThreshold-info.AdversaryThreshold))) + + // We should not require the chunk length to be so small that the number of chunks is greater than the max required + if maxChunkLength < chunkLengthForMaxRequiredNumChunks { + maxChunkLength = chunkLengthForMaxRequiredNumChunks + } if info.ChunkLength > maxChunkLength { return false, fmt.Errorf("%w: chunk length: %d, max chunk length: %d", ErrChunkLengthTooLarge, info.ChunkLength, maxChunkLength) @@ -230,6 +234,10 @@ func (c *StdAssignmentCoordinator) ValidateChunkLength(state *OperatorState, blo // too large for the constraint in ValidateChunkLength func (c *StdAssignmentCoordinator) CalculateChunkLength(state *OperatorState, blobLength, targetNumChunks uint, param *SecurityParam) (uint, error) { + if targetNumChunks != 0 { + return 0, errors.New("not supported") + } + chunkLength := uint(MinChunkLength) * 2 for { @@ -244,18 +252,6 @@ func (c *StdAssignmentCoordinator) CalculateChunkLength(state *OperatorState, bl return chunkLength / 2, nil } - if targetNumChunks != 0 { - - _, info, err := c.GetAssignments(state, blobLength, quorumInfo) - if err != nil { - return 0, err - } - - if info.TotalChunks <= targetNumChunks { - return chunkLength, nil - } - } - chunkLength *= 2 } @@ -276,7 +272,7 @@ func roundUpDivide(a, b uint) uint { } -func nextPowerOf2(d uint64) uint64 { +func nextPowerOf2(d uint) uint { nextPower := math.Ceil(math.Log2(float64(d))) - return uint64(math.Pow(2.0, nextPower)) + return uint(math.Pow(2.0, nextPower)) } diff --git a/core/assignment_test.go b/core/assignment_test.go index 656f03952f..555387ce3d 100644 --- a/core/assignment_test.go +++ b/core/assignment_test.go @@ -105,18 +105,14 @@ func FuzzOperatorAssignments(f *testing.F) { asn := &core.StdAssignmentCoordinator{} for i := 1; i < 100; i++ { - f.Add(i, true) - } - - for i := 1; i < 100; i++ { - f.Add(i, false) + f.Add(i) } for i := 0; i < 100; i++ { - f.Add(rand.Intn(254)+1, rand.Intn(2) == 0) + f.Add(rand.Intn(254) + 1) } - f.Fuzz(func(t *testing.T, numOperators int, useTargetNumChunks bool) { + f.Fuzz(func(t *testing.T, numOperators int) { // Generate a random slice of integers of length n @@ -145,16 +141,13 @@ func FuzzOperatorAssignments(f *testing.F) { blobLength := uint(rand.Intn(100000)) - targetNumChunks := uint(0) - if useTargetNumChunks { - targetNumChunks = uint(rand.Intn(1000)) - } - fmt.Println("advThreshold", advThreshold, "quorumThreshold", quorumThreshold, "numOperators", numOperators, "blobLength", blobLength) - chunkLength, err := asn.CalculateChunkLength(state.OperatorState, blobLength, targetNumChunks, param) + chunkLength, err := asn.CalculateChunkLength(state.OperatorState, blobLength, 0, param) assert.NoError(t, err) + assert.LessOrEqual(t, chunkLength, blobLength) + quorumInfo := &core.BlobQuorumInfo{ SecurityParam: *param, ChunkLength: chunkLength, @@ -164,24 +157,11 @@ func FuzzOperatorAssignments(f *testing.F) { assert.NoError(t, err) assert.True(t, ok) - assignments, info, err := asn.GetAssignments(state.OperatorState, blobLength, quorumInfo) + assignments, _, err := asn.GetAssignments(state.OperatorState, blobLength, quorumInfo) assert.NoError(t, err) // fmt.Println("advThreshold", advThreshold, "quorumThreshold", quorumThreshold, "numOperators", numOperators, "chunkLength", chunkLength, "blobLength", blobLength) - if useTargetNumChunks { - - quorumInfo.ChunkLength = chunkLength * 2 - ok, err := asn.ValidateChunkLength(state.OperatorState, blobLength, quorumInfo) - - // Make sure that the number of chunks is less than the target - // TODO: Make sure that the number of chunks is no less than half the target (this currently fails in some rare cases - // but it isn't a critical problem) - if ok && err == nil { - assert.GreaterOrEqual(t, targetNumChunks, info.TotalChunks) - } - } - // Check that each operator's assignment satisfies the security requirement for operatorID, assignment := range assignments { diff --git a/disperser/batcher/batch_confirmer_test.go b/disperser/batcher/batch_confirmer_test.go index dc1048e36a..0b51153ce0 100644 --- a/disperser/batcher/batch_confirmer_test.go +++ b/disperser/batcher/batch_confirmer_test.go @@ -269,7 +269,7 @@ func TestBatchConfirmerIteration(t *testing.T) { // Receive signatures signChan := make(chan core.SigningMessage, 4) - batchHeaderHash := [32]byte{138, 1, 226, 93, 51, 120, 236, 124, 91, 206, 100, 187, 237, 1, 193, 151, 137, 131, 30, 218, 139, 24, 221, 105, 141, 253, 242, 13, 239, 199, 179, 42} + batchHeaderHash := [32]byte{114, 82, 109, 126, 137, 173, 194, 225, 212, 234, 30, 186, 248, 74, 84, 232, 208, 148, 180, 59, 47, 132, 180, 240, 17, 196, 76, 19, 16, 64, 156, 99} for opID, opInfo := range operatorState.PrivateOperators { signChan <- core.SigningMessage{ Signature: opInfo.KeyPair.SignMessage(batchHeaderHash), diff --git a/disperser/batcher/batcher_test.go b/disperser/batcher/batcher_test.go index 0a2e8d91a7..748c4174df 100644 --- a/disperser/batcher/batcher_test.go +++ b/disperser/batcher/batcher_test.go @@ -227,7 +227,7 @@ func TestBatcherIterations(t *testing.T) { assert.NoError(t, err) count, size := components.encodingStreamer.EncodedBlobstore.GetEncodedResultSize() assert.Equal(t, 2, count) - assert.Equal(t, uint64(27631), size) + assert.Equal(t, uint64(34178), size) txn := types.NewTransaction(0, gethcommon.Address{}, big.NewInt(0), 0, big.NewInt(0), nil) components.transactor.On("BuildConfirmBatchTxn", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { diff --git a/disperser/batcher/minibatcher_test.go b/disperser/batcher/minibatcher_test.go index b8648018fc..adaac279a0 100644 --- a/disperser/batcher/minibatcher_test.go +++ b/disperser/batcher/minibatcher_test.go @@ -73,7 +73,7 @@ func newMinibatcher(t *testing.T, config batcher.MinibatcherConfig) *minibatcher SRSOrder: 3000, EncodingRequestTimeout: 5 * time.Second, EncodingQueueLimit: 10, - TargetNumChunks: 8092, + TargetNumChunks: 0, MaxBlobsToFetchFromStore: 10, FinalizationBlockDelay: 0, ChainStateTimeout: 5 * time.Second,