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

Flag guard the dual quorum in disperser #389

Merged
merged 5 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading