Skip to content

Commit

Permalink
Flag guard the dual quorum in disperser (#389)
Browse files Browse the repository at this point in the history
  • Loading branch information
jianoaix authored Mar 25, 2024
1 parent a704e2f commit 292e203
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 12 deletions.
24 changes: 16 additions & 8 deletions disperser/apiserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ func (s *DispersalServer) validateRequestAndGetBlob(ctx context.Context, req *pb
}

if len(req.GetCustomQuorumNumbers()) > 256 {
return nil, errors.New("invalid request: number of custom_quorum_numbers must not exceed 256")
return nil, errors.New("number of custom_quorum_numbers must not exceed 256")
}

quorumConfig, err := s.updateQuorumConfig(ctx)
Expand All @@ -812,7 +812,7 @@ func (s *DispersalServer) validateRequestAndGetBlob(ctx context.Context, req *pb
}

if len(req.GetCustomQuorumNumbers()) > int(quorumConfig.QuorumCount) {
return nil, errors.New("invalid request: number of custom_quorum_numbers must not exceed number of quorums")
return nil, errors.New("number of custom_quorum_numbers must not exceed number of quorums")
}

seenQuorums := make(map[uint8]struct{})
Expand All @@ -821,31 +821,39 @@ func (s *DispersalServer) validateRequestAndGetBlob(ctx context.Context, req *pb
for i := range req.GetCustomQuorumNumbers() {

if req.GetCustomQuorumNumbers()[i] > 254 {
return nil, fmt.Errorf("invalid request: quorum_numbers must be in range [0, 254], but found %d", req.GetCustomQuorumNumbers()[i])
return nil, fmt.Errorf("custom_quorum_numbers must be in range [0, 254], but found %d", req.GetCustomQuorumNumbers()[i])
}

quorumID := uint8(req.GetCustomQuorumNumbers()[i])
if quorumID >= quorumConfig.QuorumCount {
return nil, fmt.Errorf("invalid request: the quorum_numbers must be in range [0, %d], but found %d", s.quorumConfig.QuorumCount-1, quorumID)
return nil, fmt.Errorf("custom_quorum_numbers must be in range [0, %d], but found %d", s.quorumConfig.QuorumCount-1, quorumID)
}

if _, ok := seenQuorums[quorumID]; ok {
return nil, fmt.Errorf("invalid request: quorum_numbers must not contain duplicates")
return nil, fmt.Errorf("custom_quorum_numbers must not contain duplicates")
}
seenQuorums[quorumID] = struct{}{}

}

// Add the required quorums to the list of quorums to check
for _, quorumID := range quorumConfig.RequiredQuorums {
// Note: no matter if dual quorum staking is enabled or not, custom_quorum_numbers cannot
// use any required quorums that are defined onchain.
if _, ok := seenQuorums[quorumID]; ok {
return nil, fmt.Errorf("invalid request: custom_quorum_numbers should not include the required quorums %v, but required quorum %d was found", quorumConfig.RequiredQuorums, quorumID)
return nil, fmt.Errorf("custom_quorum_numbers should not include the required quorums %v, but required quorum %d was found", quorumConfig.RequiredQuorums, quorumID)
}
if s.serverConfig.EnableDualQuorums {
seenQuorums[quorumID] = struct{}{}
} else if quorumID == 0 {
// If dual quorum staking is not enabled, we only consider the quorum 0 as the
// required quorum.
seenQuorums[quorumID] = struct{}{}
}
seenQuorums[quorumID] = struct{}{}
}

if len(seenQuorums) == 0 {
return nil, fmt.Errorf("invalid request: the blob must be sent to at least one quorum")
return nil, fmt.Errorf("the blob must be sent to at least one quorum")
}

params := make([]*core.SecurityParam, len(seenQuorums))
Expand Down
4 changes: 2 additions & 2 deletions disperser/apiserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,13 @@ func TestDisperseBlobWithInvalidQuorum(t *testing.T) {
Data: data,
CustomQuorumNumbers: []uint32{2},
})
assert.ErrorContains(t, err, "invalid request: the quorum_numbers must be in range [0, 1], but found 2")
assert.ErrorContains(t, err, "custom_quorum_numbers must be in range [0, 1], but found 2")

_, err = dispersalServer.DisperseBlob(ctx, &pb.DisperseBlobRequest{
Data: data,
CustomQuorumNumbers: []uint32{0, 0},
})
assert.ErrorContains(t, err, "invalid request: quorum_numbers must not contain duplicates")
assert.ErrorContains(t, err, "custom_quorum_numbers must not contain duplicates")

}

Expand Down
5 changes: 3 additions & 2 deletions disperser/cmd/apiserver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ func NewConfig(ctx *cli.Context) (Config, error) {
config := Config{
AwsClientConfig: aws.ReadClientConfig(ctx, flags.FlagPrefix),
ServerConfig: disperser.ServerConfig{
GrpcPort: ctx.GlobalString(flags.GrpcPortFlag.Name),
GrpcTimeout: ctx.GlobalDuration(flags.GrpcTimeoutFlag.Name),
GrpcPort: ctx.GlobalString(flags.GrpcPortFlag.Name),
GrpcTimeout: ctx.GlobalDuration(flags.GrpcTimeoutFlag.Name),
EnableDualQuorums: ctx.GlobalBool(flags.EnableDualQuorums.Name),
},
BlobstoreConfig: blobstore.Config{
BucketName: ctx.GlobalString(flags.S3BucketNameFlag.Name),
Expand Down
7 changes: 7 additions & 0 deletions disperser/cmd/apiserver/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ var (
EnvVar: common.PrefixEnvVar(envVarPrefix, "RATE_BUCKET_STORE_SIZE"),
Required: false,
}
EnableDualQuorums = cli.BoolFlag{
Name: common.PrefixFlag(FlagPrefix, "enable-dual-quorums"),
Usage: "Whether to enable dual quorum staking. If false, only quorum 0 is used as required quorum",
Required: false,
EnvVar: common.PrefixEnvVar(envVarPrefix, "ENABLE_DUAL_QUORUMS"),
}
)

var requiredFlags = []cli.Flag{
Expand All @@ -104,6 +110,7 @@ var optionalFlags = []cli.Flag{
EnableRatelimiter,
BucketStoreSize,
GrpcTimeoutFlag,
EnableDualQuorums,
}

// Flags contains the list of configuration options available to the binary.
Expand Down
5 changes: 5 additions & 0 deletions disperser/server_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ const (
type ServerConfig struct {
GrpcPort string
GrpcTimeout time.Duration

// Feature flags
// Whether enable the dual quorums.
// If false, only quorum 0 will be used as required quorum.
EnableDualQuorums bool
}
2 changes: 2 additions & 0 deletions inabox/deploy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ func (env *Config) generateDisperserVars(ind int, key, address, logPath, dbPath,

DISPERSER_SERVER_BLS_OPERATOR_STATE_RETRIVER: env.EigenDA.OperatorStateRetreiver,
DISPERSER_SERVER_EIGENDA_SERVICE_MANAGER: env.EigenDA.ServiceManager,

DISPERSER_SERVER_ENABLE_DUAL_QUORUMS: "true",
}

env.applyDefaults(&v, "DISPERSER_SERVER", "dis", ind)
Expand Down
2 changes: 2 additions & 0 deletions inabox/deploy/env_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ type DisperserVars struct {
DISPERSER_SERVER_RETRIEVAL_BLOB_RATE string

DISPERSER_SERVER_RETRIEVAL_BYTE_RATE string

DISPERSER_SERVER_ENABLE_DUAL_QUORUMS string
}

func (vars DisperserVars) getEnvMap() map[string]string {
Expand Down

0 comments on commit 292e203

Please sign in to comment.