feat: module circuit breaker (#14521)
Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Julien Robert <julien@rbrt.fr> Co-authored-by: Sam Ricotta <samanthalricotta@gmail.com> Co-authored-by: samricotta <37125168+samricotta@users.noreply.github.com> Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com>
This commit is contained in:
parent
d818a628a1
commit
b8e15a7930
@ -3,7 +3,6 @@ package circuitv1
|
||||
|
||||
import (
|
||||
v1beta1 "cosmossdk.io/api/cosmos/base/query/v1beta1"
|
||||
_ "cosmossdk.io/api/cosmos/msg/v1"
|
||||
_ "cosmossdk.io/api/cosmos/query/v1"
|
||||
fmt "fmt"
|
||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||
@ -2953,72 +2952,70 @@ var file_cosmos_circuit_v1_query_proto_rawDesc = []byte{
|
||||
0x11, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e,
|
||||
0x76, 0x31, 0x1a, 0x2a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f,
|
||||
0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61,
|
||||
0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17,
|
||||
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73,
|
||||
0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f,
|
||||
0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x71, 0x75, 0x65,
|
||||
0x72, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0x2f, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x22, 0x51, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5e, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a,
|
||||
0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e,
|
||||
0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa5, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x08, 0x61, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50,
|
||||
0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d,
|
||||
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65,
|
||||
0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2f, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72,
|
||||
0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x51, 0x0a, 0x0f, 0x41, 0x63, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0a,
|
||||
0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69,
|
||||
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5e, 0x0a, 0x14,
|
||||
0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a,
|
||||
0x18, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x14, 0x44, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6c, 0x69,
|
||||
0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x32, 0xb4, 0x03, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x12, 0x89, 0x01, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x2e, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69,
|
||||
0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63,
|
||||
0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x82, 0x01, 0x0a,
|
||||
0x08, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa5, 0x01, 0x0a,
|
||||
0x10, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x48, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72,
|
||||
0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x41,
|
||||
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70,
|
||||
0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75,
|
||||
0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x22, 0x3b, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x32, 0xad, 0x03,
|
||||
0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x89, 0x01, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72,
|
||||
0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f,
|
||||
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x32, 0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x7d, 0x12, 0x82, 0x01, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
|
||||
0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69,
|
||||
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28,
|
||||
0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f,
|
||||
0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x92, 0x01, 0x0a, 0x0c, 0x44, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75,
|
||||
0x65, 0x72, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63,
|
||||
0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x69,
|
||||
0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x73, 0x12, 0x92, 0x01, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63,
|
||||
0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63,
|
||||
0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xb7, 0x01,
|
||||
0x65, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x2c, 0x88, 0xe7, 0xb0, 0x2a, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x42, 0xb7, 0x01,
|
||||
0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x69, 0x72,
|
||||
0x63, 0x75, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b,
|
||||
|
||||
@ -431,6 +431,12 @@ func (app *BaseApp) setState(mode runTxMode, header cmtproto.Header) {
|
||||
}
|
||||
}
|
||||
|
||||
// SetCircuitBreaker sets the circuit breaker for the BaseApp.
|
||||
// The circuit breaker is checked on every message execution to verify if a transaction should be executed or not.
|
||||
func (app *BaseApp) SetCircuitBreaker(cb CircuitBreaker) {
|
||||
app.msgServiceRouter.SetCircuit(cb)
|
||||
}
|
||||
|
||||
// GetConsensusParams returns the current consensus parameters from the BaseApp's
|
||||
// ParamStore. If the BaseApp has no ParamStore defined, nil is returned.
|
||||
func (app *BaseApp) GetConsensusParams(ctx sdk.Context) cmtproto.ConsensusParams {
|
||||
|
||||
10
baseapp/circuit.go
Normal file
10
baseapp/circuit.go
Normal file
@ -0,0 +1,10 @@
|
||||
package baseapp
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// CircuitBreaker is an interface that defines the methods for a circuit breaker.
|
||||
type CircuitBreaker interface {
|
||||
IsAllowed(ctx sdk.Context, typeURL string) bool
|
||||
}
|
||||
@ -26,6 +26,7 @@ type MessageRouter interface {
|
||||
type MsgServiceRouter struct {
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
routes map[string]MsgServiceHandler
|
||||
circuitBreaker CircuitBreaker
|
||||
}
|
||||
|
||||
var _ gogogrpc.Server = &MsgServiceRouter{}
|
||||
@ -37,6 +38,10 @@ func NewMsgServiceRouter() *MsgServiceRouter {
|
||||
}
|
||||
}
|
||||
|
||||
func (msr *MsgServiceRouter) SetCircuit(cb CircuitBreaker) {
|
||||
msr.circuitBreaker = cb
|
||||
}
|
||||
|
||||
// MsgServiceHandler defines a function type which handles Msg service message.
|
||||
type MsgServiceHandler = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error)
|
||||
|
||||
@ -128,6 +133,13 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter
|
||||
}
|
||||
}
|
||||
|
||||
if msr.circuitBreaker != nil {
|
||||
msgURL := sdk.MsgTypeURL(msg)
|
||||
if !msr.circuitBreaker.IsAllowed(ctx, msgURL) {
|
||||
return nil, fmt.Errorf("circuit breaker disables execution of this message: %s", msgURL)
|
||||
}
|
||||
}
|
||||
|
||||
// Call the method handler from the service description with the handler object.
|
||||
// We don't do any decoding here because the decoding was already done.
|
||||
res, err := methodHandler(handler, ctx, noopDecoder, interceptor)
|
||||
|
||||
@ -4,15 +4,12 @@ package cosmos.circuit.v1;
|
||||
option go_package = "cosmossdk.io/x/circuit/types";
|
||||
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
import "cosmos/msg/v1/msg.proto";
|
||||
import "cosmos/circuit/v1/types.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "cosmos/query/v1/query.proto";
|
||||
|
||||
// Msg defines the crisis Msg service.
|
||||
service Query {
|
||||
option (cosmos.msg.v1.service) = true;
|
||||
|
||||
// Account returns account permissions.
|
||||
rpc Account(QueryAccountRequest) returns (AccountResponse) {
|
||||
option (cosmos.query.v1.module_query_safe) = true;
|
||||
|
||||
50
simapp/ante.go
Normal file
50
simapp/ante.go
Normal file
@ -0,0 +1,50 @@
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
circuitante "cosmossdk.io/x/circuit/ante"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
)
|
||||
|
||||
// HandlerOptions are the options required for constructing a default SDK AnteHandler.
|
||||
type HandlerOptions struct {
|
||||
ante.HandlerOptions
|
||||
CircuitKeeper circuitante.CircuitBreaker
|
||||
}
|
||||
|
||||
// NewAnteHandler returns an AnteHandler that checks and increments sequence
|
||||
// numbers, checks signatures & account numbers, and deducts fees from the first
|
||||
// signer.
|
||||
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
|
||||
if options.AccountKeeper == nil {
|
||||
return nil, errors.New("account keeper is required for ante builder")
|
||||
}
|
||||
|
||||
if options.BankKeeper == nil {
|
||||
return nil, errors.New("bank keeper is required for ante builder")
|
||||
}
|
||||
|
||||
if options.SignModeHandler == nil {
|
||||
return nil, errors.New("sign mode handler is required for ante builder")
|
||||
}
|
||||
|
||||
anteDecorators := []sdk.AnteDecorator{
|
||||
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
|
||||
circuitante.NewCircuitBreakerDecorator(options.CircuitKeeper),
|
||||
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
|
||||
ante.NewValidateBasicDecorator(),
|
||||
ante.NewTxTimeoutHeightDecorator(),
|
||||
ante.NewValidateMemoDecorator(options.AccountKeeper),
|
||||
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||
ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
|
||||
ante.NewValidateSigCountDecorator(options.AccountKeeper),
|
||||
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
|
||||
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
|
||||
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
|
||||
}
|
||||
|
||||
return sdk.ChainAnteDecorators(anteDecorators...), nil
|
||||
}
|
||||
@ -36,6 +36,9 @@ import (
|
||||
upgradekeeper "cosmossdk.io/x/upgrade/keeper"
|
||||
upgradetypes "cosmossdk.io/x/upgrade/types"
|
||||
|
||||
"cosmossdk.io/x/circuit"
|
||||
circuitkeeper "cosmossdk.io/x/circuit/keeper"
|
||||
circuittypes "cosmossdk.io/x/circuit/types"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
@ -159,6 +162,7 @@ type SimApp struct {
|
||||
GroupKeeper groupkeeper.Keeper
|
||||
NFTKeeper nftkeeper.Keeper
|
||||
ConsensusParamsKeeper consensusparamkeeper.Keeper
|
||||
CircuitKeeper circuitkeeper.Keeper
|
||||
|
||||
// the module manager
|
||||
ModuleManager *module.Manager
|
||||
@ -235,7 +239,8 @@ func NewSimApp(
|
||||
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey,
|
||||
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
|
||||
govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
|
||||
evidencetypes.StoreKey, authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey,
|
||||
evidencetypes.StoreKey, circuittypes.StoreKey,
|
||||
authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey,
|
||||
)
|
||||
|
||||
// register streaming services
|
||||
@ -294,6 +299,8 @@ func NewSimApp(
|
||||
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
|
||||
)
|
||||
|
||||
app.CircuitKeeper = circuitkeeper.NewKeeper(keys[circuittypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.AccountKeeper.GetAddressCodec())
|
||||
|
||||
app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, app.MsgServiceRouter(), app.AccountKeeper)
|
||||
|
||||
groupConfig := group.DefaultConfig()
|
||||
@ -378,6 +385,7 @@ func NewSimApp(
|
||||
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
|
||||
circuit.NewAppModule(appCodec, app.CircuitKeeper),
|
||||
)
|
||||
|
||||
// BasicModuleManager defines the module BasicManager is in charge of setting up basic,
|
||||
@ -428,7 +436,7 @@ func NewSimApp(
|
||||
distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
|
||||
minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
|
||||
feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName, consensusparamtypes.ModuleName,
|
||||
vestingtypes.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName,
|
||||
}
|
||||
app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)
|
||||
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)
|
||||
@ -522,19 +530,23 @@ func NewSimApp(
|
||||
}
|
||||
|
||||
func (app *SimApp) setAnteHandler(txConfig client.TxConfig) {
|
||||
anteHandler, err := ante.NewAnteHandler(
|
||||
ante.HandlerOptions{
|
||||
AccountKeeper: app.AccountKeeper,
|
||||
BankKeeper: app.BankKeeper,
|
||||
SignModeHandler: txConfig.SignModeHandler(),
|
||||
FeegrantKeeper: app.FeeGrantKeeper,
|
||||
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||
anteHandler, err := NewAnteHandler(
|
||||
HandlerOptions{
|
||||
ante.HandlerOptions{
|
||||
AccountKeeper: app.AccountKeeper,
|
||||
BankKeeper: app.BankKeeper,
|
||||
SignModeHandler: txConfig.SignModeHandler(),
|
||||
FeegrantKeeper: app.FeeGrantKeeper,
|
||||
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||
},
|
||||
&app.CircuitKeeper,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set the AnteHandler for the app
|
||||
app.SetAnteHandler(anteHandler)
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
|
||||
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
|
||||
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
|
||||
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
|
||||
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
|
||||
crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
|
||||
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
|
||||
@ -28,6 +29,7 @@ import (
|
||||
vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
_ "cosmossdk.io/x/circuit" // import for side-effects
|
||||
_ "cosmossdk.io/x/evidence" // import for side-effects
|
||||
_ "cosmossdk.io/x/feegrant/module" // import for side-effects
|
||||
_ "cosmossdk.io/x/nft/module" // import for side-effects
|
||||
@ -48,6 +50,7 @@ import (
|
||||
_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
|
||||
|
||||
"cosmossdk.io/core/appconfig"
|
||||
circuittypes "cosmossdk.io/x/circuit/types"
|
||||
evidencetypes "cosmossdk.io/x/evidence/types"
|
||||
"cosmossdk.io/x/feegrant"
|
||||
"cosmossdk.io/x/nft"
|
||||
@ -153,6 +156,7 @@ var (
|
||||
upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
circuittypes.ModuleName,
|
||||
},
|
||||
// When ExportGenesis is not specified, the export genesis module order
|
||||
// is equal to the init genesis order
|
||||
@ -248,6 +252,10 @@ var (
|
||||
Name: consensustypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&consensusmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: circuittypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
depinject.Supply(
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"cosmossdk.io/depinject"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
circuitkeeper "cosmossdk.io/x/circuit/keeper"
|
||||
evidencekeeper "cosmossdk.io/x/evidence/keeper"
|
||||
feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
|
||||
nftkeeper "cosmossdk.io/x/nft/keeper"
|
||||
@ -81,6 +82,7 @@ type SimApp struct {
|
||||
GroupKeeper groupkeeper.Keeper
|
||||
NFTKeeper nftkeeper.Keeper
|
||||
ConsensusParamsKeeper consensuskeeper.Keeper
|
||||
CircuitBreakerKeeper circuitkeeper.Keeper
|
||||
|
||||
// simulation manager
|
||||
sm *module.SimulationManager
|
||||
@ -165,6 +167,7 @@ func NewSimApp(
|
||||
&app.GroupKeeper,
|
||||
&app.NFTKeeper,
|
||||
&app.ConsensusParamsKeeper,
|
||||
&app.CircuitBreakerKeeper,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -11,7 +11,8 @@ require (
|
||||
cosmossdk.io/math v1.0.0
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc
|
||||
cosmossdk.io/tools/confix v0.0.0-20230120150717-4f6f6c00021f
|
||||
cosmossdk.io/tools/rosetta v0.2.0
|
||||
cosmossdk.io/tools/rosetta v0.2.1
|
||||
cosmossdk.io/x/circuit v0.0.0-20230220112800-f69b9ff58fbe
|
||||
cosmossdk.io/x/evidence v0.1.0
|
||||
cosmossdk.io/x/feegrant v0.0.0-20230117113717-50e7c4a4ceff
|
||||
cosmossdk.io/x/nft v0.0.0-20230113085233-fae3332d62fc
|
||||
@ -168,7 +169,7 @@ require (
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/zondax/hid v0.9.1 // indirect
|
||||
github.com/zondax/ledger-go v0.14.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
@ -203,6 +204,7 @@ replace (
|
||||
cosmossdk.io/store => ../store
|
||||
cosmossdk.io/tools/confix => ../tools/confix
|
||||
cosmossdk.io/tools/rosetta => ../tools/rosetta
|
||||
cosmossdk.io/x/circuit => ../x/circuit
|
||||
cosmossdk.io/x/evidence => ../x/evidence
|
||||
cosmossdk.io/x/feegrant => ../x/feegrant
|
||||
cosmossdk.io/x/nft => ../x/nft
|
||||
|
||||
@ -267,7 +267,7 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
|
||||
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
@ -1078,8 +1078,8 @@ github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp
|
||||
github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c=
|
||||
github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@ -1328,7 +1328,6 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@ -39,6 +39,7 @@ require (
|
||||
cloud.google.com/go/storage v1.30.0 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20230309163709-87da587416ba // indirect
|
||||
cosmossdk.io/collections v0.1.0 // indirect
|
||||
cosmossdk.io/x/circuit v0.0.0-20230220112800-f69b9ff58fbe // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.1 // indirect
|
||||
@ -165,7 +166,7 @@ require (
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/zondax/hid v0.9.1 // indirect
|
||||
github.com/zondax/ledger-go v0.14.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
@ -196,6 +197,7 @@ replace (
|
||||
// TODO: remove me after collections v0.2.0 is released
|
||||
cosmossdk.io/collections => ../collections
|
||||
cosmossdk.io/store => ../store
|
||||
cosmossdk.io/x/circuit => ../x/circuit
|
||||
cosmossdk.io/x/evidence => ../x/evidence
|
||||
cosmossdk.io/x/feegrant => ../x/feegrant
|
||||
cosmossdk.io/x/nft => ../x/nft
|
||||
|
||||
@ -269,7 +269,7 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
|
||||
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
@ -1080,8 +1080,8 @@ github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp
|
||||
github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c=
|
||||
github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@ -1328,7 +1328,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
|
||||
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
|
||||
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
|
||||
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
|
||||
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
|
||||
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
|
||||
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
|
||||
@ -43,6 +44,7 @@ var beginBlockOrder = []string{
|
||||
"params",
|
||||
"consensus",
|
||||
"vesting",
|
||||
"circuit",
|
||||
}
|
||||
|
||||
var endBlockersOrder = []string{
|
||||
@ -64,6 +66,7 @@ var endBlockersOrder = []string{
|
||||
"consensus",
|
||||
"upgrade",
|
||||
"vesting",
|
||||
"circuit",
|
||||
}
|
||||
|
||||
var initGenesisOrder = []string{
|
||||
@ -85,6 +88,7 @@ var initGenesisOrder = []string{
|
||||
"consensus",
|
||||
"upgrade",
|
||||
"vesting",
|
||||
"circuit",
|
||||
}
|
||||
|
||||
type appConfig struct {
|
||||
@ -264,6 +268,15 @@ func NFTModule() ModuleOption {
|
||||
}
|
||||
}
|
||||
|
||||
func CircuitModule() ModuleOption {
|
||||
return func(config *appConfig) {
|
||||
config.moduleConfigs["circuit"] = &appv1alpha1.ModuleConfig{
|
||||
Name: "circuit",
|
||||
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func OmitInitGenesis() ModuleOption {
|
||||
return func(config *appConfig) {
|
||||
config.setInitGenesis = false
|
||||
|
||||
@ -98,9 +98,9 @@ func TestDeductFeesNoDelegation(t *testing.T) {
|
||||
valid: true,
|
||||
malleate: func(suite *AnteTestSuite) (TestAccount, sdk.AccAddress) {
|
||||
accs := suite.CreateTestAccounts(2)
|
||||
|
||||
suite.feeGrantKeeper.EXPECT().UseGrantedFees(gomock.Any(), accs[1].acc.GetAddress(), accs[0].acc.GetAddress(), gomock.Any(), gomock.Any()).Return(nil).Times(2)
|
||||
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[1].acc.GetAddress(), authtypes.FeeCollectorName, gomock.Any()).Return(nil).Times(2)
|
||||
|
||||
return accs[0], accs[1].acc.GetAddress()
|
||||
},
|
||||
},
|
||||
|
||||
@ -87,7 +87,6 @@ https://github.com/cosmos/cosmos-sdk/blob/main/proto/cosmos/circuit/v1/tx.proto#
|
||||
This message is expected to fail if:
|
||||
|
||||
* the granter is not an account with permission level `LEVEL_SUPER_ADMIN` or the module authority
|
||||
* if the type urls does not exist <!-- TODO: is this possible?-->
|
||||
|
||||
### MsgTripCircuitBreaker
|
||||
|
||||
@ -98,7 +97,6 @@ https://github.com/cosmos/cosmos-sdk/blob/main/proto/cosmos/circuit/v1/tx.proto#
|
||||
This message is expected to fail if:
|
||||
|
||||
* if the signer does not have a permission level with the ability to disable the specified type url message
|
||||
* if the type urls does not exist <!-- TODO: is this possible?-->
|
||||
|
||||
### MsgResetCircuitBreaker
|
||||
|
||||
@ -108,8 +106,46 @@ https://github.com/cosmos/cosmos-sdk/blob/main/proto/cosmos/circuit/v1/tx.proto#
|
||||
|
||||
This message is expected to fail if:
|
||||
|
||||
* if the type urls does not exist <!-- TODO: is this possible?-->
|
||||
* if the type url is not disabled
|
||||
|
||||
* `## Events` - list and describe event tags used
|
||||
* `## Client` - list and describe CLI commands and gRPC and REST endpoints
|
||||
## Events - list and describe event tags
|
||||
|
||||
The circuit module emits the following events:
|
||||
|
||||
### Message Events
|
||||
|
||||
#### MsgAuthorizeCircuitBreaker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------|---------------|---------------------------|
|
||||
| string | granter | {granteeAddress} |
|
||||
| string | grantee | {granterAddress} |
|
||||
| string | permission | {granteePermissions} |
|
||||
| message | module | circuit |
|
||||
| message | action | authorize_circuit_breaker |
|
||||
|
||||
#### MsgTripCircuitBreaker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------|---------------|--------------------|
|
||||
| string | authority | {authorityAddress} |
|
||||
| []string | msg_urls | []string{msg_urls} |
|
||||
| message | module | circuit |
|
||||
| message | action | trip_circuit_breaker |
|
||||
|
||||
#### ResetCircuitBreaker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------|---------------|--------------------|
|
||||
| string | authority | {authorityAddress} |
|
||||
| []string | msg_urls | []string{msg_urls} |
|
||||
| message | module | circuit |
|
||||
| message | action | reset_circuit_breaker |
|
||||
|
||||
|
||||
## Keys - list of key prefixes used by the circuit module
|
||||
|
||||
* `AccountPermissionPrefix` - `0x01`
|
||||
* `DisableListPrefix` - `0x02`
|
||||
|
||||
## Client - list and describe CLI commands and gRPC and REST endpoints
|
||||
|
||||
33
x/circuit/ante/circuit.go
Normal file
33
x/circuit/ante/circuit.go
Normal file
@ -0,0 +1,33 @@
|
||||
package ante
|
||||
|
||||
import (
|
||||
"github.com/cockroachdb/errors"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// CircuitBreaker is an interface that defines the methods for a circuit breaker.
|
||||
type CircuitBreaker interface {
|
||||
IsAllowed(ctx sdk.Context, typeURL string) bool
|
||||
}
|
||||
|
||||
// CircuitBreakerDecorator is an AnteDecorator that checks if the transaction type is allowed to enter the mempool or be executed
|
||||
type CircuitBreakerDecorator struct {
|
||||
circuitKeeper CircuitBreaker
|
||||
}
|
||||
|
||||
func NewCircuitBreakerDecorator(ck CircuitBreaker) CircuitBreakerDecorator {
|
||||
return CircuitBreakerDecorator{
|
||||
circuitKeeper: ck,
|
||||
}
|
||||
}
|
||||
|
||||
func (cbd CircuitBreakerDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||
// loop through all the messages and check if the message type is allowed
|
||||
for _, msg := range tx.GetMsgs() {
|
||||
if !cbd.circuitKeeper.IsAllowed(ctx, sdk.MsgTypeURL(msg)) {
|
||||
return ctx, errors.New("tx type not allowed")
|
||||
}
|
||||
}
|
||||
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
91
x/circuit/ante/circuit_test.go
Normal file
91
x/circuit/ante/circuit_test.go
Normal file
@ -0,0 +1,91 @@
|
||||
package ante_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
cbtypes "cosmossdk.io/x/circuit/types"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
|
||||
"cosmossdk.io/x/circuit/ante"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
ctx sdk.Context
|
||||
mockStoreKey storetypes.StoreKey
|
||||
mockMsgURL string
|
||||
mockclientCtx client.Context
|
||||
txBuilder client.TxBuilder
|
||||
}
|
||||
|
||||
type MockCircuitBreaker struct {
|
||||
isAllowed bool
|
||||
}
|
||||
|
||||
func (m MockCircuitBreaker) IsAllowed(ctx sdk.Context, typeURL string) bool {
|
||||
return typeURL == "/cosmos.circuit.v1.MsgAuthorizeCircuitBreaker"
|
||||
}
|
||||
|
||||
func initFixture(t *testing.T) *fixture {
|
||||
mockStoreKey := storetypes.NewKVStoreKey("test")
|
||||
encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{})
|
||||
mockclientCtx := client.Context{}.
|
||||
WithTxConfig(encCfg.TxConfig).
|
||||
WithClient(clitestutil.NewMockCometRPC(abci.ResponseQuery{}))
|
||||
|
||||
return &fixture{
|
||||
ctx: testutil.DefaultContextWithDB(t, mockStoreKey, storetypes.NewTransientStoreKey("transient_test")).Ctx.WithBlockHeader(cmproto.Header{}),
|
||||
mockStoreKey: mockStoreKey,
|
||||
mockMsgURL: "test",
|
||||
mockclientCtx: mockclientCtx,
|
||||
txBuilder: mockclientCtx.TxConfig.NewTxBuilder(),
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreakerDecorator(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
_, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
||||
testcases := []struct {
|
||||
msg sdk.Msg
|
||||
allowed bool
|
||||
}{
|
||||
{msg: &cbtypes.MsgAuthorizeCircuitBreaker{
|
||||
Grantee: "cosmos1fghij",
|
||||
Granter: "cosmos1abcde",
|
||||
}, allowed: true},
|
||||
{msg: testdata.NewTestMsg(addr1), allowed: false},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
// Circuit breaker is allowed to pass through all transactions
|
||||
circuitBreaker := &MockCircuitBreaker{true}
|
||||
// CircuitBreakerDecorator AnteHandler should always return success
|
||||
decorator := ante.NewCircuitBreakerDecorator(circuitBreaker)
|
||||
|
||||
f.txBuilder.SetMsgs(tc.msg)
|
||||
tx := f.txBuilder.GetTx()
|
||||
|
||||
_, err := decorator.AnteHandle(f.ctx, tx, false, func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
if tc.allowed {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Equal(t, "tx type not allowed", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
119
x/circuit/client/cli/query.go
Normal file
119
x/circuit/client/cli/query.go
Normal file
@ -0,0 +1,119 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the parent command for all circuit CLI query commands.
|
||||
func GetQueryCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Querying commands for the circuit module",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
GetDisabeListCmd(),
|
||||
GetAccountCmd(),
|
||||
GetAccountsCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func GetDisabeListCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "disabled-list",
|
||||
Short: "Query for all disabled message types",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
res, err := queryClient.DisabledList(cmd.Context(), &types.QueryDisabledListRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func GetAccountCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "account [address]",
|
||||
Short: "Query for account permissions",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
res, err := queryClient.Account(cmd.Context(), &types.QueryAccountRequest{Address: addr.String()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func GetAccountsCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "accounts",
|
||||
Short: "Query for all account permissions",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
res, err := queryClient.Accounts(cmd.Context(), &types.QueryAccountsRequest{Pagination: pageReq})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
129
x/circuit/client/cli/tx.go
Normal file
129
x/circuit/client/cli/tx.go
Normal file
@ -0,0 +1,129 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewTxCmd returns a root CLI command handler for all x/circuit transaction commands.
|
||||
func NewTxCmd() *cobra.Command {
|
||||
txCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Circuit transaction subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
txCmd.AddCommand(
|
||||
AuthorizeCircuitBreakerCmd(),
|
||||
TripCircuitBreakerCmd(),
|
||||
)
|
||||
|
||||
return txCmd
|
||||
}
|
||||
|
||||
// AuthorizeCircuitBreakerCmd returns a CLI command handler for creating a MsgAuthorizeCircuitBreaker transaction.
|
||||
func AuthorizeCircuitBreakerCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authorize [grantee] [permission_level] [limit_type_urls] --from [granter]",
|
||||
Short: "Authorize an account to trip the circuit breaker.",
|
||||
Long: `Authorize an account to trip the circuit breaker.
|
||||
"SOME_MSGS" = 1,
|
||||
"ALL_MSGS" = 2,
|
||||
"SUPER_ADMIN" = 3,`,
|
||||
Example: fmt.Sprintf(`%s circuit authorize [address] 0 "cosmos.bank.v1beta1.MsgSend,cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName),
|
||||
Args: cobra.RangeArgs(3, 4),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
grantee, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lvl, err := math.ParseUint(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var typeUrls []string
|
||||
if len(args) == 4 {
|
||||
typeUrls = strings.Split(args[2], ",")
|
||||
}
|
||||
|
||||
permission := types.Permissions{Level: types.Permissions_Level(lvl.Uint64()), LimitTypeUrls: typeUrls}
|
||||
|
||||
msg := types.NewMsgAuthorizeCircuitBreaker(clientCtx.GetFromAddress().String(), grantee.String(), &permission)
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// TripCircuitBreakerCmd returns a CLI command handler for creating a MsgTripCircuitBreaker transaction.
|
||||
func TripCircuitBreakerCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "disable [type_url]",
|
||||
Short: "disable a message from being executed",
|
||||
Example: fmt.Sprintf(`%s circuit disable "cosmos.bank.v1beta1.MsgSend,cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgTripCircuitBreaker(clientCtx.GetFromAddress().String(), strings.Split(args[0], ","))
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// ResetCircuitBreakerCmd returns a CLI command handler for creating a MsgRestCircuitBreaker transaction.
|
||||
func ResetCircuitBreakerCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reset [type_url]",
|
||||
Short: "Enable a message to be executed",
|
||||
Example: fmt.Sprintf(`%s circuit reset "cosmos.bank.v1beta1.MsgSend,cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgTypeUrls := strings.Split(args[0], ",")
|
||||
|
||||
msg := types.NewMsgResetCircuitBreaker(clientCtx.GetFromAddress().String(), msgTypeUrls)
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -1,87 +0,0 @@
|
||||
Feature: MsgAuthorizeCircuitBreaker
|
||||
Circuit breaker actions can be authorized:
|
||||
- when the granter is a super-admin
|
||||
- when the permissions are valid
|
||||
|
||||
Rule: the granter must be a super-admin
|
||||
|
||||
Example: granter is a super-admin
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{ "level": "LEVEL_ALL_MSGS" }
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: granter has no permissions
|
||||
Given "acct1" has no permissions
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{ "level": "LEVEL_ALL_MSGS" }
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Example: granter has all msg's permissions
|
||||
Given "acct1" has permission "LEVEL_ALL_MSGS"
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{ "level": "LEVEL_ALL_MSGS" }
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Rule: limit_msg_types must be used with LEVEL_SOME_MSGS
|
||||
|
||||
Example: granting LEVEL_SOME_MSGS with limit_msg_types
|
||||
Given "acct1" has permission "LEVEL_ALL_MSGS"
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{
|
||||
"level": "LEVEL_SOME_MSGS"
|
||||
"limit_msg_types": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: granting LEVEL_SOME_MSGS without limit_msg_types
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{ "level": "LEVEL_SOME_MSGS" }
|
||||
"""
|
||||
Then expect an "invalid request" error
|
||||
|
||||
Example: granting LEVEL_ALL_MSGS with limit_msg_types
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to grant "acct2" the permissions
|
||||
"""
|
||||
{
|
||||
"level": "LEVEL_ALL_MSGS",
|
||||
"limit_msg_types": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "invalid request" error
|
||||
|
||||
Example: attempting to revoke with limit_msg_types
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to revoke "acct2" the permissions
|
||||
"""
|
||||
{
|
||||
"level": "LEVEL_NONE_UNSPECIFIED",
|
||||
"limit_msg_types": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "invalid request" error
|
||||
|
||||
Rule: permissions can be revoked using LEVEL_NONE_UNSPECIFIED
|
||||
|
||||
Example: revoking permissions
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
And "acct2" has permission "LEVEL_ALL_MSGS"
|
||||
When "acct1" attempts to revoke "acct2" the permissions
|
||||
"""
|
||||
{
|
||||
"level": "LEVEL_NONE_UNSPECIFIED",
|
||||
}
|
||||
"""
|
||||
Then expect sucesss
|
||||
And expect that "acct2" has no permissions
|
||||
@ -1,65 +0,0 @@
|
||||
Feature: MsgResetCircuitBreaker
|
||||
- Circuit breaker can be reset:
|
||||
- when the permissions are valid
|
||||
|
||||
Rule: caller must have a permission to reset the circuit
|
||||
|
||||
Example: caller attempts to reset a disabled message
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to enable a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: caller has no permissions
|
||||
Given "acct1" has no permissions
|
||||
When "acct1" attempts to reset a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Example: caller attempts to reset a disabled message
|
||||
Given "acct1" has permission "LEVEL_ALL_MSGS"
|
||||
When "acct1" attempts to reset a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: caller attempts to reset a message they have permission to trip
|
||||
Given "acct1" has permission to trip circuit breaker for "cosmos.bank.v1beta1.MsgSend"
|
||||
When "acct1" attempts to reset a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: caller attempts to reset a message they don't have permission to trip
|
||||
Given "acct1" has permission to trip circuit breaker for "cosmos.bank.v1beta1.MsgSend"
|
||||
When "acct1" attempts to reset a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MultiSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: caller attempts to reset a message that has been tripped
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN" & "cosmos.bank.v1beta1.MultiSend" has been enabled
|
||||
When "acct1" attempts to reset a disabled message
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MultiSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "msg enabled" error
|
||||
@ -1,76 +0,0 @@
|
||||
Feature: MsgTripCircuitBreaker
|
||||
Circuit breaker can disable message execution:
|
||||
- when the caller trips the circuitbreaker for a message(s)
|
||||
- when the caller has the correct permissions
|
||||
|
||||
Rule: a user must have permission to trip the circuit breaker for a message(s)
|
||||
|
||||
Example: user is a super admin
|
||||
Given "acct1" has permission "LEVEL_SUPER_ADMIN"
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: user has no permissions
|
||||
Given "acct1" has no permissions
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Example: user has permission for all messages
|
||||
Given "acct1" has permission "LEVEL_ALL_MSGS"
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MsgSend"
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: user has permission for the messages
|
||||
Given "acct1" has permission to disable "cosmos.bank.v1beta1.MsgSend" and "cosmos.staking.v1beta1.MsgDelegate"
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msgs": ["cosmos.bank.v1beta1.MsgSend",cosmos.staking.v1beta1.MsgDelegate"]
|
||||
}
|
||||
"""
|
||||
Then expect success
|
||||
|
||||
Example: user does not have permission for 1 of the messages in the list
|
||||
Given "acct1" has permission to disable "cosmos.bank.v1beta1.MsgSend"
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msgs": ["cosmos.bank.v1beta1.MsgSend","cosmos.staking.v1beta1.MsgCreateValidator"]
|
||||
}
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Example: user does not have permission for the message
|
||||
Given "acct1" has permission to diable "cosmos.bank.v1beta1.MsgSend"
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MultiSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "unauthorized" error
|
||||
|
||||
Example: user tries to trip an already tripped circuit breaker
|
||||
Given "acct1" has permission to diable "cosmos.bank.v1beta1.MsgSend" & is already tripped
|
||||
When "acct1" attempts to disable msg execution
|
||||
"""
|
||||
{
|
||||
"msg": "cosmos.bank.v1beta1.MultiSend"
|
||||
}
|
||||
"""
|
||||
Then expect an "msg disabled" error
|
||||
106
x/circuit/go.mod
106
x/circuit/go.mod
@ -1,91 +1,163 @@
|
||||
module github.com/cosmos/cosmos-sdk/x/circuit
|
||||
module cosmossdk.io/x/circuit
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.4.1
|
||||
cosmossdk.io/core v0.7.0
|
||||
cosmossdk.io/depinject v1.0.0-alpha.3
|
||||
cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4
|
||||
cosmossdk.io/math v1.0.0
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc
|
||||
github.com/cockroachdb/errors v1.9.1
|
||||
github.com/cometbft/cometbft v0.37.1
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230424095137-b73c17cb9cc8
|
||||
github.com/cosmos/gogoproto v1.4.10
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/regen-network/gocuke v0.6.2
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
|
||||
google.golang.org/grpc v1.55.0
|
||||
gotest.tools/v3 v3.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.4.1 // indirect
|
||||
cosmossdk.io/collections v0.1.0 // indirect
|
||||
cosmossdk.io/core v0.7.0 // indirect
|
||||
cosmossdk.io/depinject v1.0.0-alpha.3 // indirect
|
||||
cosmossdk.io/errors v1.0.0-beta.7 // indirect
|
||||
cosmossdk.io/log v1.1.0 // indirect
|
||||
cosmossdk.io/math v1.0.0 // indirect
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc // indirect
|
||||
cosmossdk.io/x/tx v0.5.5 // indirect
|
||||
cosmossdk.io/x/tx v0.6.3 // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.1 // indirect
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
|
||||
github.com/DataDog/zstd v1.5.2 // indirect
|
||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||
github.com/bufbuild/protocompile v0.5.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.1.0 // indirect
|
||||
github.com/cockroachdb/errors v1.9.1 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||
github.com/cockroachdb/pebble v0.0.0-20230412222916-60cfeb46143b // indirect
|
||||
github.com/cockroachdb/redact v1.1.3 // indirect
|
||||
github.com/cometbft/cometbft v0.37.1 // indirect
|
||||
github.com/cometbft/cometbft-db v0.7.0 // indirect
|
||||
github.com/confio/ics23/go v0.9.0 // indirect
|
||||
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||
github.com/cosmos/cosmos-db v1.0.0-rc.1 // indirect
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect
|
||||
github.com/cucumber/common/gherkin/go/v22 v22.0.0 // indirect
|
||||
github.com/cucumber/common/messages/go/v17 v17.1.1 // indirect
|
||||
github.com/cosmos/go-bip39 v1.0.0 // indirect
|
||||
github.com/cosmos/gogogateway v1.2.0 // indirect
|
||||
github.com/cosmos/iavl v0.21.0 // indirect
|
||||
github.com/cosmos/ics23/go v0.10.0 // indirect
|
||||
github.com/cosmos/ledger-cosmos-go v0.13.0 // indirect
|
||||
github.com/creachadair/taskgroup v0.4.2 // indirect
|
||||
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.20.0 // indirect
|
||||
github.com/go-kit/kit v0.12.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/gofrs/uuid v4.3.0+incompatible // indirect
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/orderedcode v0.0.1 // indirect
|
||||
github.com/gorilla/handlers v1.5.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
github.com/gtank/merlin v0.1.1 // indirect
|
||||
github.com/gtank/ristretto255 v0.1.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.9 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
|
||||
github.com/huandu/skiplist v1.2.0 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||
github.com/improbable-eng/grpc-web v0.15.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/linxGnu/grocksdb v1.7.16 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.15.1 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.43.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/rs/cors v1.8.3 // indirect
|
||||
github.com/rs/zerolog v1.29.1 // indirect
|
||||
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.15.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
|
||||
github.com/tendermint/go-amino v0.16.0 // indirect
|
||||
github.com/tidwall/btree v1.6.0 // indirect
|
||||
github.com/zondax/hid v0.9.1 // indirect
|
||||
github.com/zondax/ledger-go v0.14.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
nhooyr.io/websocket v1.8.6 // indirect
|
||||
pgregory.net/rapid v0.5.7 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
cosmossdk.io/x/tx => ../tx
|
||||
github.com/cosmos/cosmos-sdk => ../../.
|
||||
cosmossdk.io/store => ../../store
|
||||
cosmossdk.io/collections => ../../collections
|
||||
)
|
||||
|
||||
721
x/circuit/go.sum
721
x/circuit/go.sum
File diff suppressed because it is too large
Load Diff
56
x/circuit/keeper/genesis.go
Normal file
56
x/circuit/keeper/genesis.go
Normal file
@ -0,0 +1,56 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func (k *Keeper) ExportGenesis(ctx sdk.Context) (data *types.GenesisState) {
|
||||
var (
|
||||
permissions []*types.GenesisAccountPermissions
|
||||
disabledMsgs []string
|
||||
)
|
||||
|
||||
k.IteratePermissions(ctx, func(address []byte, perm types.Permissions) (stop bool) {
|
||||
add, err := k.addressCodec.BytesToString(address)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Convert the Permissions struct to a GenesisAccountPermissions struct
|
||||
// and add it to the permissions slice
|
||||
permissions = append(permissions, &types.GenesisAccountPermissions{
|
||||
Address: add,
|
||||
Permissions: &perm,
|
||||
})
|
||||
return false
|
||||
})
|
||||
|
||||
k.IterateDisableLists(ctx, func(address []byte, perm types.Permissions) (stop bool) {
|
||||
disabledMsgs = append(disabledMsgs, perm.LimitTypeUrls...)
|
||||
return false
|
||||
})
|
||||
|
||||
return &types.GenesisState{
|
||||
AccountPermissions: permissions,
|
||||
DisabledTypeUrls: disabledMsgs,
|
||||
}
|
||||
}
|
||||
|
||||
// InitGenesis initializes the bank module's state from a given genesis state.
|
||||
func (k *Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) {
|
||||
for _, accounts := range genState.AccountPermissions {
|
||||
add, err := k.addressCodec.StringToBytes(accounts.Address)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set the permissions for the account
|
||||
if err := k.SetPermissions(ctx, add, accounts.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
for _, url := range genState.DisabledTypeUrls {
|
||||
// Set the disabled type urls
|
||||
k.DisableMsg(ctx, url)
|
||||
}
|
||||
}
|
||||
125
x/circuit/keeper/keeper.go
Normal file
125
x/circuit/keeper/keeper.go
Normal file
@ -0,0 +1,125 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
proto "github.com/cosmos/gogoproto/proto"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Keeper defines the circuit module's keeper.
|
||||
type Keeper struct {
|
||||
storekey storetypes.StoreKey
|
||||
|
||||
authority []byte
|
||||
|
||||
addressCodec address.Codec
|
||||
}
|
||||
|
||||
// NewKeeper constructs a new Circuit Keeper instance
|
||||
func NewKeeper(storeKey storetypes.StoreKey, authority string, addressCodec address.Codec) Keeper {
|
||||
auth, err := addressCodec.StringToBytes(authority)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return Keeper{
|
||||
storekey: storeKey,
|
||||
authority: auth,
|
||||
addressCodec: addressCodec,
|
||||
}
|
||||
}
|
||||
|
||||
func (k *Keeper) GetAuthority() []byte {
|
||||
return k.authority
|
||||
}
|
||||
|
||||
func (k *Keeper) GetPermissions(ctx sdk.Context, address []byte) (*types.Permissions, error) {
|
||||
store := ctx.KVStore(k.storekey)
|
||||
|
||||
key := types.CreateAddressPrefix(address)
|
||||
bz := store.Get(key)
|
||||
|
||||
perms := &types.Permissions{}
|
||||
if err := proto.Unmarshal(bz, perms); err != nil {
|
||||
return &types.Permissions{}, err
|
||||
}
|
||||
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
func (k *Keeper) SetPermissions(ctx sdk.Context, address []byte, perms *types.Permissions) error {
|
||||
store := ctx.KVStore(k.storekey)
|
||||
|
||||
bz, err := proto.Marshal(perms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key := types.CreateAddressPrefix(address)
|
||||
store.Set(key, bz)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *Keeper) IsAllowed(ctx sdk.Context, msgURL string) bool {
|
||||
store := ctx.KVStore(k.storekey)
|
||||
return !store.Has(types.CreateDisableMsgPrefix(msgURL))
|
||||
}
|
||||
|
||||
func (k *Keeper) DisableMsg(ctx sdk.Context, msgURL string) {
|
||||
ctx.KVStore(k.storekey).Set(types.CreateDisableMsgPrefix(msgURL), []byte{})
|
||||
}
|
||||
|
||||
func (k *Keeper) EnableMsg(ctx sdk.Context, msgURL string) {
|
||||
ctx.KVStore(k.storekey).Delete(types.CreateDisableMsgPrefix(msgURL))
|
||||
}
|
||||
|
||||
func (k *Keeper) IteratePermissions(ctx sdk.Context, cb func(address []byte, perms types.Permissions) (stop bool)) {
|
||||
store := ctx.KVStore(k.storekey)
|
||||
iter := storetypes.KVStorePrefixIterator(store, types.AccountPermissionPrefix)
|
||||
defer func(iter storetypes.Iterator) {
|
||||
err := iter.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(iter)
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
var perms types.Permissions
|
||||
err := proto.Unmarshal(iter.Value(), &perms)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if cb(iter.Key()[len(types.AccountPermissionPrefix):], perms) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (k *Keeper) IterateDisableLists(ctx sdk.Context, cb func(url []byte, perms types.Permissions) (stop bool)) {
|
||||
store := ctx.KVStore(k.storekey)
|
||||
|
||||
iter := storetypes.KVStorePrefixIterator(store, types.AccountPermissionPrefix)
|
||||
defer func(iter storetypes.Iterator) {
|
||||
err := iter.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(iter)
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
var perms types.Permissions
|
||||
err := proto.Unmarshal(iter.Value(), &perms)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if cb(iter.Key()[len(types.DisableListPrefix):], perms) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
135
x/circuit/keeper/keeper_test.go
Normal file
135
x/circuit/keeper/keeper_test.go
Normal file
@ -0,0 +1,135 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
cmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/circuit/keeper"
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
ctx sdk.Context
|
||||
keeper keeper.Keeper
|
||||
mockAddr []byte
|
||||
mockPerms types.Permissions
|
||||
mockMsgURL string
|
||||
}
|
||||
|
||||
func initFixture(t *testing.T) *fixture {
|
||||
ac := addresscodec.NewBech32Codec("cosmos")
|
||||
mockStoreKey := storetypes.NewKVStoreKey("test")
|
||||
k := keeper.NewKeeper(mockStoreKey, authtypes.NewModuleAddress("gov").String(), ac)
|
||||
|
||||
bz, err := ac.StringToBytes(authtypes.NewModuleAddress("gov").String())
|
||||
require.NoError(t, err)
|
||||
|
||||
return &fixture{
|
||||
ctx: testutil.DefaultContextWithDB(t, mockStoreKey, storetypes.NewTransientStoreKey("transient_test")).Ctx.WithBlockHeader(cmproto.Header{}),
|
||||
keeper: k,
|
||||
mockAddr: bz,
|
||||
mockPerms: types.Permissions{
|
||||
Level: 3,
|
||||
},
|
||||
mockMsgURL: "mock_url",
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAuthority(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
authority := f.keeper.GetAuthority()
|
||||
require.True(t, bytes.Equal(f.mockAddr, authority))
|
||||
}
|
||||
|
||||
func TestGetAndSetPermissions(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
// Set the permissions for the mock address.
|
||||
|
||||
err := f.keeper.SetPermissions(f.ctx, f.mockAddr, &f.mockPerms)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Retrieve the permissions for the mock address.
|
||||
perms, err := f.keeper.GetPermissions(f.ctx, f.mockAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
//// Assert that the retrieved permissions match the expected value.
|
||||
require.Equal(t, &f.mockPerms, perms)
|
||||
}
|
||||
|
||||
func TestIteratePermissions(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
// Define a set of mock permissions
|
||||
mockPerms := []types.Permissions{
|
||||
{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{"url1", "url2"}},
|
||||
{Level: types.Permissions_LEVEL_ALL_MSGS},
|
||||
{Level: types.Permissions_LEVEL_NONE_UNSPECIFIED},
|
||||
}
|
||||
|
||||
// Set the permissions for a set of mock addresses
|
||||
mockAddrs := [][]byte{
|
||||
[]byte("mock_address_1"),
|
||||
[]byte("mock_address_2"),
|
||||
[]byte("mock_address_3"),
|
||||
}
|
||||
for i, addr := range mockAddrs {
|
||||
f.keeper.SetPermissions(f.ctx, addr, &mockPerms[i])
|
||||
}
|
||||
|
||||
// Define a variable to store the returned permissions
|
||||
var returnedPerms []types.Permissions
|
||||
|
||||
// Iterate through the permissions and append them to the returnedPerms slice
|
||||
f.keeper.IteratePermissions(f.ctx, func(address []byte, perms types.Permissions) (stop bool) {
|
||||
returnedPerms = append(returnedPerms, perms)
|
||||
return false
|
||||
})
|
||||
|
||||
// Assert that the returned permissions match the set mock permissions
|
||||
require.Equal(t, mockPerms, returnedPerms)
|
||||
}
|
||||
|
||||
func TestIterateDisabledList(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
mockPerms := []types.Permissions{
|
||||
{Level: types.Permissions_LEVEL_SUPER_ADMIN, LimitTypeUrls: []string{"url1", "url2"}},
|
||||
{Level: types.Permissions_LEVEL_ALL_MSGS},
|
||||
{Level: types.Permissions_LEVEL_NONE_UNSPECIFIED},
|
||||
}
|
||||
|
||||
// Set the permissions for a set of mock addresses
|
||||
mockAddrs := [][]byte{
|
||||
[]byte("mock_address_1"),
|
||||
[]byte("mock_address_2"),
|
||||
[]byte("mock_address_3"),
|
||||
}
|
||||
|
||||
for i, addr := range mockAddrs {
|
||||
f.keeper.SetPermissions(f.ctx, addr, &mockPerms[i])
|
||||
}
|
||||
|
||||
// Define a variable to store the returned disabled URLs
|
||||
var returnedDisabled []types.Permissions
|
||||
|
||||
f.keeper.IterateDisableLists(f.ctx, func(address []byte, perms types.Permissions) bool {
|
||||
returnedDisabled = append(returnedDisabled, perms)
|
||||
return false
|
||||
})
|
||||
|
||||
// Assert that the returned disabled URLs match the set mock disabled URLs
|
||||
require.Equal(t, mockPerms[0].LimitTypeUrls, returnedDisabled[0].LimitTypeUrls)
|
||||
require.Equal(t, mockPerms[1].LimitTypeUrls, returnedDisabled[1].LimitTypeUrls)
|
||||
require.Equal(t, mockPerms[2].LimitTypeUrls, returnedDisabled[2].LimitTypeUrls)
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/regen-network/gocuke"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestAuthorize(t *testing.T) {
|
||||
t.Skip("TODO: uncomment this after implementing")
|
||||
gocuke.NewRunner(t, &authorizeSuite{}).Path("../features/msg_authorize.feature").Run()
|
||||
}
|
||||
|
||||
type authorizeSuite struct {
|
||||
*baseFixture
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) Before(t *testing.T) {
|
||||
s.baseFixture = initFixture(t)
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) HasPermission(a, b string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) HasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) AttemptsToGrantThePermissions(a, b string, c gocuke.DocString) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) ExpectSuccess() {
|
||||
assert.NilError(s.t, s.err)
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) ExpectAnError(a string) {
|
||||
assert.Error(s.t, s.err, a)
|
||||
}
|
||||
|
||||
func (s *authorizeSuite) ExpectThatHasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/regen-network/gocuke"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestReset(t *testing.T) {
|
||||
t.Skip("TODO: uncomment this after implementing")
|
||||
gocuke.NewRunner(t, &resetSuite{}).Path("../features/msg_reset.feature").Run()
|
||||
}
|
||||
|
||||
type resetSuite struct {
|
||||
*baseFixture
|
||||
}
|
||||
|
||||
func (s *resetSuite) Before(t *testing.T) {
|
||||
s.baseFixture = initFixture(t)
|
||||
}
|
||||
|
||||
func (s *resetSuite) HasPermission(a, b string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *resetSuite) HasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *resetSuite) AttemptsToResetCircuit(a, b string, c gocuke.DocString) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *resetSuite) ExpectSuccess() {
|
||||
assert.NilError(s.t, s.err)
|
||||
}
|
||||
|
||||
func (s *resetSuite) ExpectAnError(a string) {
|
||||
assert.Error(s.t, s.err, a)
|
||||
}
|
||||
|
||||
func (s *resetSuite) ExpectThatHasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
179
x/circuit/keeper/msg_server.go
Normal file
179
x/circuit/keeper/msg_server.go
Normal file
@ -0,0 +1,179 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
"strings"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
type msgServer struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
// NewMsgServerImpl returns an implementation of the bank MsgServer interface
|
||||
// for the provided Keeper.
|
||||
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
|
||||
return &msgServer{Keeper: keeper}
|
||||
}
|
||||
|
||||
func (srv msgServer) AuthorizeCircuitBreaker(goCtx context.Context, msg *types.MsgAuthorizeCircuitBreaker) (*types.MsgAuthorizeCircuitBreakerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
address, err := srv.addressCodec.StringToBytes(msg.Granter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if the granter is the module authority no need to check perms
|
||||
if !bytes.Equal(address, srv.GetAuthority()) {
|
||||
// Check that the authorizer has the permission level of "super admin"
|
||||
perms, err := srv.GetPermissions(ctx, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user permission does not exist %w", err)
|
||||
}
|
||||
|
||||
if perms.Level != types.Permissions_LEVEL_SUPER_ADMIN {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "only super admins can authorize users")
|
||||
}
|
||||
}
|
||||
|
||||
grantee, err := srv.addressCodec.StringToBytes(msg.Grantee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Append the account in the msg to the store's set of authorized super admins
|
||||
if err = srv.SetPermissions(ctx, grantee, msg.Permissions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
"authorize_circuit_breaker",
|
||||
sdk.NewAttribute("granter", msg.Granter),
|
||||
sdk.NewAttribute("grantee", msg.Grantee),
|
||||
sdk.NewAttribute("permission", msg.Permissions.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgAuthorizeCircuitBreakerResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (srv msgServer) TripCircuitBreaker(goCtx context.Context, msg *types.MsgTripCircuitBreaker) (*types.MsgTripCircuitBreakerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
address, err := srv.addressCodec.StringToBytes(msg.Authority)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check that the account has the permissions
|
||||
perms, err := srv.GetPermissions(ctx, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user permission does not exist %w", err)
|
||||
}
|
||||
|
||||
store := ctx.KVStore(srv.storekey)
|
||||
|
||||
switch {
|
||||
case perms.Level == types.Permissions_LEVEL_SUPER_ADMIN || perms.Level == types.Permissions_LEVEL_ALL_MSGS || bytes.Equal(address, srv.GetAuthority()):
|
||||
for _, msgTypeURL := range msg.MsgTypeUrls {
|
||||
// check if the message is in the list of allowed messages
|
||||
if !srv.IsAllowed(ctx, msgTypeURL) {
|
||||
return nil, fmt.Errorf("message %s is already disabled", msgTypeURL)
|
||||
}
|
||||
store.Set(types.CreateDisableMsgPrefix(msgTypeURL), []byte{0x01})
|
||||
}
|
||||
case perms.Level == types.Permissions_LEVEL_SOME_MSGS:
|
||||
for _, msgTypeURL := range msg.MsgTypeUrls {
|
||||
// check if the message is in the list of allowed messages
|
||||
if !srv.IsAllowed(ctx, msgTypeURL) {
|
||||
return nil, fmt.Errorf("message %s is already disabled", msgTypeURL)
|
||||
}
|
||||
for _, msgurl := range perms.LimitTypeUrls {
|
||||
if msgTypeURL == msgurl {
|
||||
store.Set(types.CreateDisableMsgPrefix(msgTypeURL), []byte{0x01})
|
||||
} else {
|
||||
return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "account does not have permission to trip circuit breaker for message %s", msgTypeURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "account does not have permission to trip circuit breaker")
|
||||
}
|
||||
|
||||
var urls string
|
||||
if len(msg.GetMsgTypeUrls()) > 1 {
|
||||
urls = strings.Join(msg.GetMsgTypeUrls(), ",")
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
"trip_circuit_breaker",
|
||||
sdk.NewAttribute("authority", msg.Authority),
|
||||
sdk.NewAttribute("msg_url", urls),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgTripCircuitBreakerResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ResetCircuitBreaker resumes processing of Msg's in the state machine that
|
||||
// have been been paused using TripCircuitBreaker.
|
||||
func (srv msgServer) ResetCircuitBreaker(goCtx context.Context, msg *types.MsgResetCircuitBreaker) (*types.MsgResetCircuitBreakerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
keeper := srv.Keeper
|
||||
|
||||
address, err := srv.addressCodec.StringToBytes(msg.Authority)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the permissions for the account specified in the msg.Authority field
|
||||
perms, err := keeper.GetPermissions(ctx, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user permission does not exist %w", err)
|
||||
}
|
||||
|
||||
store := ctx.KVStore(srv.storekey)
|
||||
|
||||
if perms.Level == types.Permissions_LEVEL_SUPER_ADMIN || perms.Level == types.Permissions_LEVEL_ALL_MSGS || perms.Level == types.Permissions_LEVEL_SOME_MSGS || bytes.Equal(address, srv.GetAuthority()) {
|
||||
// add all msg type urls to the disable list
|
||||
for _, msgTypeURL := range msg.MsgTypeUrls {
|
||||
if srv.IsAllowed(ctx, msgTypeURL) {
|
||||
return nil, fmt.Errorf("message %s is not disabled", msgTypeURL)
|
||||
}
|
||||
store.Delete(types.CreateDisableMsgPrefix(msgTypeURL))
|
||||
}
|
||||
} else {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "account does not have permission to reset circuit breaker")
|
||||
}
|
||||
|
||||
var urls string
|
||||
if len(msg.GetMsgTypeUrls()) > 1 {
|
||||
urls = strings.Join(msg.GetMsgTypeUrls(), ",")
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
"reset_circuit_breaker",
|
||||
sdk.NewAttribute("authority", msg.Authority),
|
||||
sdk.NewAttribute("msg_url", urls),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgResetCircuitBreakerResponse{Success: true}, nil
|
||||
}
|
||||
223
x/circuit/keeper/msg_server_test.go
Normal file
223
x/circuit/keeper/msg_server_test.go
Normal file
@ -0,0 +1,223 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const msgSend = "cosmos.bank.v1beta1.MsgSend"
|
||||
|
||||
func Test_AuthorizeCircuitBreaker(t *testing.T) {
|
||||
ft := setupFixture(t)
|
||||
|
||||
srv := msgServer{
|
||||
Keeper: ft.Keeper,
|
||||
}
|
||||
|
||||
// add a new super admin
|
||||
adminPerms := &types.Permissions{Level: types.Permissions_LEVEL_SUPER_ADMIN, LimitTypeUrls: []string{""}}
|
||||
msg := &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[1], Permissions: adminPerms}
|
||||
_, err := srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
add1, err := ft.Keeper.addressCodec.StringToBytes(addresses[1])
|
||||
require.NoError(t, err)
|
||||
|
||||
perms, err := ft.Keeper.GetPermissions(ft.Ctx, add1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, adminPerms, perms, "admin perms are not the same")
|
||||
|
||||
// add a super user
|
||||
allmsgs := &types.Permissions{Level: types.Permissions_LEVEL_ALL_MSGS, LimitTypeUrls: []string{""}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[2], Permissions: allmsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
add2, err := ft.Keeper.addressCodec.StringToBytes(addresses[2])
|
||||
require.NoError(t, err)
|
||||
|
||||
perms, err = ft.Keeper.GetPermissions(ft.Ctx, add2)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, allmsgs, perms, "admin perms are not the same")
|
||||
|
||||
// unauthorized user who does not have perms trying to authorize
|
||||
superPerms := &types.Permissions{Level: types.Permissions_LEVEL_SUPER_ADMIN, LimitTypeUrls: []string{}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[3], Grantee: addresses[2], Permissions: superPerms}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.Error(t, err, "user with no permission should fail in authorizing others")
|
||||
|
||||
// user with permission level all_msgs tries to grant another user perms
|
||||
somePerms := &types.Permissions{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[2], Grantee: addresses[3], Permissions: somePerms}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.Error(t, err, "user[2] does not have permission to grant others permission")
|
||||
|
||||
// user successfully grants another user perms to a specific permission
|
||||
|
||||
somemsgs := &types.Permissions{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{msgSend}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[3], Permissions: somemsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
add3, err := ft.Keeper.addressCodec.StringToBytes(addresses[3])
|
||||
require.NoError(t, err)
|
||||
|
||||
perms, err = ft.Keeper.GetPermissions(ft.Ctx, add3)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, somemsgs, perms, "admin perms are not the same")
|
||||
|
||||
add4, err := ft.Keeper.addressCodec.StringToBytes(addresses[4])
|
||||
require.NoError(t, err)
|
||||
|
||||
perms, err = ft.Keeper.GetPermissions(ft.Ctx, add4)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, &types.Permissions{Level: types.Permissions_LEVEL_NONE_UNSPECIFIED, LimitTypeUrls: nil}, perms, "user should have no perms by default")
|
||||
|
||||
// admin tries grants another user permission ALL_MSGS with limited urls populated
|
||||
invalidmsgs := &types.Permissions{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{msgSend}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[4], Permissions: invalidmsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_TripCircuitBreaker(t *testing.T) {
|
||||
ft := setupFixture(t)
|
||||
|
||||
srv := msgServer{
|
||||
Keeper: ft.Keeper,
|
||||
}
|
||||
url := msgSend
|
||||
|
||||
// admin trips circuit breaker
|
||||
admintrip := &types.MsgTripCircuitBreaker{Authority: addresses[0], MsgTypeUrls: []string{url}}
|
||||
_, err := srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
allowed := ft.Keeper.IsAllowed(ft.Ctx, url)
|
||||
require.False(t, allowed, "circuit breaker should be tripped")
|
||||
|
||||
// user with all messages trips circuit breaker
|
||||
// add a super user
|
||||
allmsgs := &types.Permissions{Level: types.Permissions_LEVEL_ALL_MSGS, LimitTypeUrls: []string{""}}
|
||||
msg := &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[1], Permissions: allmsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// try to trip the circuit breaker
|
||||
url2 := "cosmos.staking.v1beta1.MsgDelegate"
|
||||
superTrip := &types.MsgTripCircuitBreaker{Authority: addresses[1], MsgTypeUrls: []string{url2}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, superTrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
allowed = ft.Keeper.IsAllowed(ft.Ctx, url2)
|
||||
require.False(t, allowed, "circuit breaker should be tripped")
|
||||
|
||||
// user with no permission attempts to trips circuit breaker
|
||||
unknownTrip := &types.MsgTripCircuitBreaker{Authority: addresses[4], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, unknownTrip)
|
||||
require.Error(t, err)
|
||||
|
||||
// user has permission to trip circuit breaker for two messages but only has permission for one
|
||||
url, url2 = "cosmos.staking.v1beta1.MsgCreateValidator", "cosmos.staking.v1beta1.MsgEditValidator"
|
||||
somemsgs := &types.Permissions{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{url}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[2], Permissions: somemsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// try to trip two messages but user only has permission for one
|
||||
someTrip := &types.MsgTripCircuitBreaker{Authority: addresses[2], MsgTypeUrls: []string{url, url2}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, someTrip)
|
||||
require.ErrorContains(t, err, "MsgEditValidator")
|
||||
|
||||
// user tries to trip an already tripped circuit breaker
|
||||
alreadyTripped := "cosmos.bank.v1beta1.MsgSend"
|
||||
twoTrip := &types.MsgTripCircuitBreaker{Authority: addresses[1], MsgTypeUrls: []string{alreadyTripped}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, twoTrip)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func Test_ResetCircuitBreaker(t *testing.T) {
|
||||
ft := setupFixture(t)
|
||||
|
||||
srv := msgServer{
|
||||
Keeper: ft.Keeper,
|
||||
}
|
||||
|
||||
// admin resets circuit breaker
|
||||
url := "cosmos.bank.v1beta1.MsgSend"
|
||||
// admin trips circuit breaker
|
||||
admintrip := &types.MsgTripCircuitBreaker{Authority: addresses[0], MsgTypeUrls: []string{url}}
|
||||
_, err := srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
allowed := ft.Keeper.IsAllowed(ft.Ctx, url)
|
||||
require.False(t, allowed, "circuit breaker should be tripped")
|
||||
|
||||
adminReset := &types.MsgResetCircuitBreaker{Authority: addresses[0], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.ResetCircuitBreaker(ft.Ctx, adminReset)
|
||||
require.NoError(t, err)
|
||||
|
||||
allowed = ft.Keeper.IsAllowed(ft.Ctx, url)
|
||||
require.True(t, allowed, "circuit breaker should be reset")
|
||||
|
||||
// user has no permission to reset circuit breaker
|
||||
// admin trips circuit breaker
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
allowed = ft.Keeper.IsAllowed(ft.Ctx, url)
|
||||
require.False(t, allowed, "circuit breaker should be tripped")
|
||||
|
||||
unknownUserReset := &types.MsgResetCircuitBreaker{Authority: addresses[1], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.ResetCircuitBreaker(ft.Ctx, unknownUserReset)
|
||||
require.Error(t, err)
|
||||
|
||||
allowed = ft.Keeper.IsAllowed(ft.Ctx, url)
|
||||
require.False(t, allowed, "circuit breaker should be reset")
|
||||
|
||||
// user with all messages resets circuit breaker
|
||||
allmsgs := &types.Permissions{Level: types.Permissions_LEVEL_ALL_MSGS, LimitTypeUrls: []string{""}}
|
||||
msg := &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[1], Permissions: allmsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// trip the circuit breaker
|
||||
url2 := "cosmos.staking.v1beta1.MsgDelegate"
|
||||
admintrip = &types.MsgTripCircuitBreaker{Authority: addresses[0], MsgTypeUrls: []string{url2}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
// user with all messages resets circuit breaker
|
||||
allMsgsReset := &types.MsgResetCircuitBreaker{Authority: addresses[1], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.ResetCircuitBreaker(ft.Ctx, allMsgsReset)
|
||||
require.NoError(t, err)
|
||||
|
||||
// user tries to reset an message they dont have permission to reset
|
||||
|
||||
url = "cosmos.staking.v1beta1.MsgCreateValidator"
|
||||
// give restricted perms to a user
|
||||
someMsgs := &types.Permissions{Level: types.Permissions_LEVEL_SOME_MSGS, LimitTypeUrls: []string{url2}}
|
||||
msg = &types.MsgAuthorizeCircuitBreaker{Granter: addresses[0], Grantee: addresses[2], Permissions: someMsgs}
|
||||
_, err = srv.AuthorizeCircuitBreaker(ft.Ctx, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
admintrip = &types.MsgTripCircuitBreaker{Authority: addresses[0], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.NoError(t, err)
|
||||
|
||||
// user with all messages resets circuit breaker
|
||||
someMsgsReset := &types.MsgResetCircuitBreaker{Authority: addresses[2], MsgTypeUrls: []string{url}}
|
||||
_, err = srv.ResetCircuitBreaker(ft.Ctx, someMsgsReset)
|
||||
require.NoError(t, err)
|
||||
|
||||
// user tries to reset an already reset circuit breaker
|
||||
admintrip = &types.MsgTripCircuitBreaker{Authority: addresses[1], MsgTypeUrls: []string{url2}}
|
||||
_, err = srv.TripCircuitBreaker(ft.Ctx, admintrip)
|
||||
require.Error(t, err)
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/regen-network/gocuke"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestTrip(t *testing.T) {
|
||||
t.Skip("TODO: uncomment this after implementing")
|
||||
gocuke.NewRunner(t, &tripSuite{}).Path("../features/msg_trip.feature").Run()
|
||||
}
|
||||
|
||||
type tripSuite struct {
|
||||
*baseFixture
|
||||
}
|
||||
|
||||
func (s *tripSuite) Before(t *testing.T) {
|
||||
s.baseFixture = initFixture(t)
|
||||
}
|
||||
|
||||
func (s *tripSuite) HasPermission(a, b string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *tripSuite) HasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *tripSuite) AttemptsToTripCircuit(a, b string, c gocuke.DocString) {
|
||||
panic("PENDING")
|
||||
}
|
||||
|
||||
func (s *tripSuite) ExpectSuccess() {
|
||||
assert.NilError(s.t, s.err)
|
||||
}
|
||||
|
||||
func (s *tripSuite) ExpectAnError(a string) {
|
||||
assert.Error(s.t, s.err, a)
|
||||
}
|
||||
|
||||
func (s *tripSuite) ExpectThatHasNoPermissions(a string) {
|
||||
panic("PENDING")
|
||||
}
|
||||
90
x/circuit/keeper/query.go
Normal file
90
x/circuit/keeper/query.go
Normal file
@ -0,0 +1,90 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"cosmossdk.io/store/prefix"
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
)
|
||||
|
||||
var _ types.QueryServer = QueryServer{}
|
||||
|
||||
type QueryServer struct {
|
||||
keeper Keeper
|
||||
}
|
||||
|
||||
// NewMsgServerImpl returns an implementation of the bank MsgServer interface
|
||||
// for the provided Keeper.
|
||||
func NewQueryServer(keeper Keeper) types.QueryServer {
|
||||
return &QueryServer{keeper: keeper}
|
||||
}
|
||||
|
||||
// Account returns account permissions.
|
||||
func (qs QueryServer) Account(c context.Context, req *types.QueryAccountRequest) (*types.AccountResponse, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
add, err := qs.keeper.addressCodec.StringToBytes(req.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
perms, err := qs.keeper.GetPermissions(sdkCtx, add)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.AccountResponse{Permission: perms}, nil
|
||||
}
|
||||
|
||||
// Account returns account permissions.
|
||||
func (qs QueryServer) Accounts(c context.Context, req *types.QueryAccountsRequest) (*types.AccountsResponse, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(c)
|
||||
// Iterate over accounts and perform the callback
|
||||
|
||||
var accounts []*types.GenesisAccountPermissions
|
||||
store := sdkCtx.KVStore(qs.keeper.storekey)
|
||||
accountsStore := prefix.NewStore(store, types.AccountPermissionPrefix)
|
||||
|
||||
pageRes, err := query.Paginate(accountsStore, req.Pagination, func(key, value []byte) error {
|
||||
perm := &types.Permissions{}
|
||||
if err := proto.Unmarshal(value, perm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove key suffix
|
||||
address, err := qs.keeper.addressCodec.BytesToString(bytes.TrimRight(key, "\x00"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
accounts = append(accounts, &types.GenesisAccountPermissions{
|
||||
Address: address,
|
||||
Permissions: perm,
|
||||
})
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.AccountsResponse{Accounts: accounts, Pagination: pageRes}, nil
|
||||
}
|
||||
|
||||
// DisabledList returns a list of disabled message urls
|
||||
func (qs QueryServer) DisabledList(c context.Context, req *types.QueryDisabledListRequest) (*types.DisabledListResponse, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(c)
|
||||
// Iterate over disabled list and perform the callback
|
||||
|
||||
var msgs []string
|
||||
qs.keeper.IterateDisableLists(sdkCtx, func(address []byte, perm types.Permissions) (stop bool) {
|
||||
msgs = append(msgs, perm.LimitTypeUrls...)
|
||||
return false
|
||||
})
|
||||
|
||||
return &types.DisabledListResponse{DisabledList: msgs}, nil
|
||||
}
|
||||
77
x/circuit/keeper/query_test.go
Normal file
77
x/circuit/keeper/query_test.go
Normal file
@ -0,0 +1,77 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestQueryAccount(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := setupFixture(t)
|
||||
|
||||
add, err := f.Keeper.addressCodec.StringToBytes(addresses[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
err = f.Keeper.SetPermissions(f.Ctx, add, &f.MockPerms)
|
||||
require.NoError(t, err)
|
||||
|
||||
// create a new query server
|
||||
qs := QueryServer{keeper: f.Keeper}
|
||||
|
||||
// test the Account method
|
||||
res, err := qs.Account(f.Ctx, &types.QueryAccountRequest{Address: addresses[0]})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, res.Permission.Level, types.Permissions_Level(3))
|
||||
require.Equal(t, res.Permission.LimitTypeUrls, []string{
|
||||
"test",
|
||||
})
|
||||
}
|
||||
|
||||
func TestQueryAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := setupFixture(t)
|
||||
|
||||
add, err := f.Keeper.addressCodec.StringToBytes(addresses[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
err = f.Keeper.SetPermissions(f.Ctx, add, &f.MockPerms)
|
||||
require.NoError(t, err)
|
||||
|
||||
// create a new query server
|
||||
qs := QueryServer{keeper: f.Keeper}
|
||||
|
||||
// test the Accounts method
|
||||
res1, err := qs.Accounts(f.Ctx, &types.QueryAccountsRequest{
|
||||
Pagination: &query.PageRequest{Limit: 10},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, a := range res1.Accounts {
|
||||
require.Equal(t, addresses[0], a.Address)
|
||||
require.Equal(t, f.MockPerms, *a.Permissions)
|
||||
}
|
||||
|
||||
require.NotNil(t, res1)
|
||||
}
|
||||
|
||||
func TestQueryDisabledList(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := setupFixture(t)
|
||||
|
||||
add, err := f.Keeper.addressCodec.StringToBytes(addresses[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
err = f.Keeper.SetPermissions(f.Ctx, add, &f.MockPerms)
|
||||
require.NoError(t, err)
|
||||
|
||||
// create a new query server
|
||||
qs := QueryServer{keeper: f.Keeper}
|
||||
|
||||
// test the DisabledList method
|
||||
disabledList, err := qs.DisabledList(f.Ctx, &types.QueryDisabledListRequest{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"test"}, disabledList.DisabledList)
|
||||
}
|
||||
@ -2,23 +2,46 @@ package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
cmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
)
|
||||
|
||||
type baseFixture struct {
|
||||
t *testing.T
|
||||
err error
|
||||
|
||||
// TODO: uncomment these after implementing.
|
||||
// ctx context.Context
|
||||
|
||||
// k Keeper
|
||||
// addrs []sdk.AccAddress
|
||||
// storeKey *storetypes.KVStoreKey
|
||||
// sdkCtx sdk.Context
|
||||
var addresses = []string{
|
||||
"cosmos1zglwfu6xjzvzagqcmvzewyzjp9xwqw5qwrr8n9",
|
||||
"cosmos1p8s0p6gqc6c9gt77lgr2qqujz49huhu6a80smx",
|
||||
"cosmos1qasf9ehx8m7cnat39ndc74rx3fg7z66u8lw0fd",
|
||||
"cosmos1uxrdj5zfuudhypsmmjxnj4gpu432ycht06a05a",
|
||||
"cosmos1wn7k8a7fwpmrwnm94ndj0germfnxnhl6hs8spj",
|
||||
}
|
||||
|
||||
func initFixture(t *testing.T) *baseFixture {
|
||||
s := &baseFixture{t: t}
|
||||
|
||||
return s
|
||||
type fixture struct {
|
||||
Ctx sdk.Context
|
||||
Keeper Keeper
|
||||
MockPerms types.Permissions
|
||||
MockMsgURL string
|
||||
}
|
||||
|
||||
func setupFixture(t *testing.T) *fixture {
|
||||
mockStoreKey := storetypes.NewKVStoreKey("circuit")
|
||||
keeperX := NewKeeper(mockStoreKey, addresses[0], addresscodec.NewBech32Codec("cosmos"))
|
||||
mockMsgURL := "mock_url"
|
||||
mockCtx := testutil.DefaultContextWithDB(t, mockStoreKey, storetypes.NewTransientStoreKey("transient_test"))
|
||||
ctx := mockCtx.Ctx.WithBlockHeader(cmproto.Header{})
|
||||
mockPerms := types.Permissions{
|
||||
Level: 3,
|
||||
LimitTypeUrls: []string{"test"},
|
||||
}
|
||||
|
||||
return &fixture{
|
||||
Ctx: ctx,
|
||||
Keeper: keeperX,
|
||||
MockPerms: mockPerms,
|
||||
MockMsgURL: mockMsgURL,
|
||||
}
|
||||
}
|
||||
|
||||
184
x/circuit/module.go
Normal file
184
x/circuit/module.go
Normal file
@ -0,0 +1,184 @@
|
||||
package circuit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
modulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/depinject"
|
||||
store "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/circuit/client/cli"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/x/circuit/keeper"
|
||||
"cosmossdk.io/x/circuit/types"
|
||||
)
|
||||
|
||||
// ConsensusVersion defines the current circuit module consensus version.
|
||||
const ConsensusVersion = 1
|
||||
|
||||
var (
|
||||
_ module.AppModuleGenesis = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the circuit module.
|
||||
type AppModuleBasic struct {
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
// Name returns the circuit module's name.
|
||||
func (AppModuleBasic) Name() string { return types.ModuleName }
|
||||
|
||||
// RegisterLegacyAminoCodec registers the circuit module's types on the LegacyAmino codec.
|
||||
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
types.RegisterLegacyAminoCodec(cdc)
|
||||
}
|
||||
|
||||
// DefaultGenesis returns default genesis state as raw bytes for the circuit
|
||||
// module.
|
||||
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
|
||||
return cdc.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
// ValidateGenesis performs genesis state validation for the circuit module.
|
||||
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
||||
}
|
||||
|
||||
return data.Validate()
|
||||
}
|
||||
|
||||
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the circuit module.
|
||||
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
|
||||
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the circuit module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
}
|
||||
|
||||
// GetQueryCmd returns no root query command for the circuit module.
|
||||
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
}
|
||||
|
||||
// RegisterInterfaces registers interfaces and implementations of the circuit module.
|
||||
func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
types.RegisterInterfaces(registry)
|
||||
}
|
||||
|
||||
// AppModule implements an application module for the circuit module.
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
|
||||
keeper keeper.Keeper
|
||||
}
|
||||
|
||||
var _ appmodule.AppModule = AppModule{}
|
||||
|
||||
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
|
||||
func (am AppModule) IsOnePerModuleType() {}
|
||||
|
||||
// IsAppModule implements the appmodule.AppModule interface.
|
||||
func (am AppModule) IsAppModule() {}
|
||||
|
||||
// RegisterServices registers module services.
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
|
||||
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServer(am.keeper))
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
||||
keeper: keeper,
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the circuit module's name.
|
||||
func (AppModule) Name() string { return types.ModuleName }
|
||||
|
||||
// RegisterInvariants registers the circuit module invariants.
|
||||
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
|
||||
}
|
||||
|
||||
// ConsensusVersion implements AppModule/ConsensusVersion.
|
||||
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }
|
||||
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
start := time.Now()
|
||||
var genesisState types.GenesisState
|
||||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
telemetry.MeasureSince(start, "InitGenesis", "crisis", "unmarshal")
|
||||
|
||||
am.keeper.InitGenesis(ctx, &genesisState)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
// ExportGenesis returns the exported genesis state as raw bytes for the circuit
|
||||
// module.
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
||||
gs := am.keeper.ExportGenesis(ctx)
|
||||
return cdc.MustMarshalJSON(gs)
|
||||
}
|
||||
|
||||
func init() {
|
||||
appmodule.Register(
|
||||
&modulev1.Module{},
|
||||
appmodule.Provide(ProvideModule),
|
||||
)
|
||||
}
|
||||
|
||||
type Inputs struct {
|
||||
depinject.In
|
||||
|
||||
Config *modulev1.Module
|
||||
Cdc codec.Codec
|
||||
Key *store.KVStoreKey
|
||||
|
||||
AddressCodec address.Codec
|
||||
}
|
||||
|
||||
type Outputs struct {
|
||||
depinject.Out
|
||||
|
||||
CircuitKeeper keeper.Keeper
|
||||
Module appmodule.AppModule
|
||||
}
|
||||
|
||||
func ProvideModule(in Inputs) Outputs {
|
||||
// default to governance authority if not provided
|
||||
authority := authtypes.NewModuleAddress("gov")
|
||||
if in.Config.Authority != "" {
|
||||
authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
|
||||
}
|
||||
|
||||
circuitkeeper := keeper.NewKeeper(
|
||||
in.Key,
|
||||
authority.String(),
|
||||
in.AddressCodec,
|
||||
)
|
||||
m := NewAppModule(in.Cdc, circuitkeeper)
|
||||
|
||||
return Outputs{CircuitKeeper: circuitkeeper, Module: m}
|
||||
}
|
||||
48
x/circuit/types/codec.go
Normal file
48
x/circuit/types/codec.go
Normal file
@ -0,0 +1,48 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec"
|
||||
govcodec "github.com/cosmos/cosmos-sdk/x/gov/codec"
|
||||
groupcodec "github.com/cosmos/cosmos-sdk/x/group/codec"
|
||||
)
|
||||
|
||||
var (
|
||||
amino = codec.NewLegacyAmino()
|
||||
ModuleCdc = codec.NewAminoCodec(amino)
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterLegacyAminoCodec(amino)
|
||||
cryptocodec.RegisterCrypto(amino)
|
||||
sdk.RegisterLegacyAminoCodec(amino)
|
||||
|
||||
// Register all Amino interfaces and concrete types on the authz and gov Amino codec so that this can later be
|
||||
// used to properly serialize MsgGrant, MsgExec and MsgSubmitProposal instances
|
||||
RegisterLegacyAminoCodec(authzcodec.Amino)
|
||||
RegisterLegacyAminoCodec(govcodec.Amino)
|
||||
RegisterLegacyAminoCodec(groupcodec.Amino)
|
||||
}
|
||||
|
||||
// RegisterLegacyAminoCodec registers the necessary x/bank interfaces and concrete types
|
||||
// on the provided LegacyAmino codec. These types are used for Amino JSON serialization.
|
||||
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
legacy.RegisterAminoMsg(cdc, &MsgAuthorizeCircuitBreaker{}, "cosmos-sdk/MsgAuthorizeCircuitBreaker")
|
||||
legacy.RegisterAminoMsg(cdc, &MsgResetCircuitBreaker{}, "cosmos-sdk/MsgResetCircuitBreaker")
|
||||
legacy.RegisterAminoMsg(cdc, &MsgTripCircuitBreaker{}, "cosmos-sdk/MsgTripCircuitBreaker")
|
||||
}
|
||||
|
||||
// RegisterInterfaces registers the interfaces types with the interface registry.
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterImplementations((*sdk.Msg)(nil),
|
||||
&MsgAuthorizeCircuitBreaker{},
|
||||
&MsgResetCircuitBreaker{},
|
||||
&MsgTripCircuitBreaker{},
|
||||
)
|
||||
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
|
||||
}
|
||||
31
x/circuit/types/genesis.go
Normal file
31
x/circuit/types/genesis.go
Normal file
@ -0,0 +1,31 @@
|
||||
package types
|
||||
|
||||
import "fmt"
|
||||
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{}
|
||||
}
|
||||
|
||||
func (gs *GenesisState) Validate() error {
|
||||
for _, account := range gs.AccountPermissions {
|
||||
if account.Address == "" {
|
||||
return fmt.Errorf("invalid account address: %s", account.Address)
|
||||
}
|
||||
if account.Permissions == nil {
|
||||
return fmt.Errorf("account has empty permissions, account address: %s", account.Address)
|
||||
}
|
||||
|
||||
if err := CheckPermission(account); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckPermission(account *GenesisAccountPermissions) error {
|
||||
if account.Permissions.Level != Permissions_LEVEL_ALL_MSGS && account.Permissions.Level != Permissions_LEVEL_SOME_MSGS && account.Permissions.Level != Permissions_LEVEL_SUPER_ADMIN {
|
||||
return fmt.Errorf("invalid permission level account address: %s, permission level: %s", account.Address, account.Permissions.Level)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
32
x/circuit/types/keys.go
Normal file
32
x/circuit/types/keys.go
Normal file
@ -0,0 +1,32 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// ModuleName defines the module name
|
||||
ModuleName = "circuit"
|
||||
|
||||
// StoreKey defines the primary module store key
|
||||
StoreKey = ModuleName
|
||||
|
||||
// RouterKey defines the module's message routing key
|
||||
RouterKey = ModuleName
|
||||
)
|
||||
|
||||
// KVStore keys
|
||||
var (
|
||||
AccountPermissionPrefix = []byte{0x01}
|
||||
DisableListPrefix = []byte{0x02}
|
||||
)
|
||||
|
||||
func CreateAddressPrefix(account []byte) []byte {
|
||||
key := make([]byte, len(AccountPermissionPrefix)+len(account)+1)
|
||||
copy(key, AccountPermissionPrefix)
|
||||
copy(key[len(AccountPermissionPrefix):], account)
|
||||
return key
|
||||
}
|
||||
|
||||
func CreateDisableMsgPrefix(msgURL string) []byte {
|
||||
key := make([]byte, len(DisableListPrefix)+len(msgURL)+1)
|
||||
copy(key, DisableListPrefix)
|
||||
copy(key[len(DisableListPrefix):], msgURL)
|
||||
return key
|
||||
}
|
||||
90
x/circuit/types/msgs.go
Normal file
90
x/circuit/types/msgs.go
Normal file
@ -0,0 +1,90 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgAuthorizeCircuitBreaker{}
|
||||
_ sdk.Msg = &MsgTripCircuitBreaker{}
|
||||
_ sdk.Msg = &MsgResetCircuitBreaker{}
|
||||
)
|
||||
|
||||
// NewMsgAuthorizeCircuitBreaker creates a new MsgAuthorizeCircuitBreaker instance.
|
||||
func NewMsgAuthorizeCircuitBreaker(granter, grantee string, permission *Permissions) *MsgAuthorizeCircuitBreaker {
|
||||
return &MsgAuthorizeCircuitBreaker{
|
||||
Granter: granter,
|
||||
Grantee: grantee,
|
||||
Permissions: permission,
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (m MsgAuthorizeCircuitBreaker) Route() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (m MsgAuthorizeCircuitBreaker) Type() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (m MsgAuthorizeCircuitBreaker) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
|
||||
}
|
||||
|
||||
// GetSigners returns the expected signers for a MsgAuthorizeCircuitBreaker.
|
||||
func (m MsgAuthorizeCircuitBreaker) GetSigners() []sdk.AccAddress {
|
||||
granter := sdk.MustAccAddressFromBech32(m.Granter)
|
||||
|
||||
return []sdk.AccAddress{granter}
|
||||
}
|
||||
|
||||
// NewMsgTripCircuitBreaker creates a new MsgTripCircuitBreaker instance.
|
||||
func NewMsgTripCircuitBreaker(authority string, urls []string) *MsgTripCircuitBreaker {
|
||||
return &MsgTripCircuitBreaker{
|
||||
Authority: authority,
|
||||
MsgTypeUrls: urls,
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (m MsgTripCircuitBreaker) Route() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (m MsgTripCircuitBreaker) Type() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (m MsgTripCircuitBreaker) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
|
||||
}
|
||||
|
||||
// GetSigners returns the expected signers for a MsgTripCircuitBreaker.
|
||||
func (m MsgTripCircuitBreaker) GetSigners() []sdk.AccAddress {
|
||||
granter := sdk.MustAccAddressFromBech32(m.Authority)
|
||||
|
||||
return []sdk.AccAddress{granter}
|
||||
}
|
||||
|
||||
// NewMsgResetCircuitBreaker creates a new MsgResetCircuitBreaker instance.
|
||||
func NewMsgResetCircuitBreaker(authority string, urls []string) *MsgResetCircuitBreaker {
|
||||
return &MsgResetCircuitBreaker{
|
||||
Authority: authority,
|
||||
MsgTypeUrls: urls,
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (m MsgResetCircuitBreaker) Route() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (m MsgResetCircuitBreaker) Type() string { return sdk.MsgTypeURL(&m) }
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (m MsgResetCircuitBreaker) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
|
||||
}
|
||||
|
||||
// GetSigners returns the expected signers for a MsgResetCircuitBreaker.
|
||||
func (m MsgResetCircuitBreaker) GetSigners() []sdk.AccAddress {
|
||||
granter := sdk.MustAccAddressFromBech32(m.Authority)
|
||||
|
||||
return []sdk.AccAddress{granter}
|
||||
}
|
||||
@ -6,7 +6,6 @@ package types
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
_ "github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
query "github.com/cosmos/cosmos-sdk/types/query"
|
||||
grpc1 "github.com/cosmos/gogoproto/grpc"
|
||||
proto "github.com/cosmos/gogoproto/proto"
|
||||
@ -314,41 +313,40 @@ func init() {
|
||||
func init() { proto.RegisterFile("cosmos/circuit/v1/query.proto", fileDescriptor_87c65073a3d3c1e1) }
|
||||
|
||||
var fileDescriptor_87c65073a3d3c1e1 = []byte{
|
||||
// 531 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xcf, 0x6b, 0x13, 0x41,
|
||||
0x14, 0xc7, 0x33, 0x2d, 0xb5, 0xed, 0x6b, 0x45, 0x1d, 0x0b, 0x86, 0x6d, 0xbb, 0xd6, 0x2d, 0x36,
|
||||
0xa1, 0x96, 0x1d, 0x12, 0xc1, 0x8b, 0x20, 0x28, 0x62, 0x3d, 0x78, 0x68, 0x73, 0xf4, 0xa0, 0x4c,
|
||||
0x76, 0x87, 0x65, 0x30, 0xd9, 0xd9, 0xee, 0xdb, 0x04, 0x8b, 0x08, 0xd2, 0x93, 0xde, 0x44, 0xff,
|
||||
0x06, 0xef, 0x1e, 0xfc, 0x23, 0x3c, 0x16, 0xbc, 0x78, 0x94, 0x44, 0xf0, 0xdf, 0x90, 0xec, 0xce,
|
||||
0x6c, 0x36, 0x76, 0x6a, 0x8f, 0x33, 0xef, 0x7d, 0xbf, 0xf3, 0x79, 0x3f, 0x76, 0x61, 0x33, 0x50,
|
||||
0xd8, 0x57, 0xc8, 0x02, 0x99, 0x06, 0x03, 0x99, 0xb1, 0x61, 0x8b, 0x1d, 0x0d, 0x44, 0x7a, 0xec,
|
||||
0x27, 0xa9, 0xca, 0x14, 0xbd, 0x56, 0x84, 0x7d, 0x1d, 0xf6, 0x87, 0x2d, 0x67, 0x57, 0x2b, 0xba,
|
||||
0x1c, 0x45, 0x91, 0xcb, 0x86, 0xad, 0xae, 0xc8, 0x78, 0x8b, 0x25, 0x3c, 0x92, 0x31, 0xcf, 0xa4,
|
||||
0x8a, 0x0b, 0xb9, 0x73, 0x43, 0xe7, 0xf6, 0x31, 0x9a, 0x38, 0xf7, 0x31, 0xd2, 0x01, 0xcb, 0xb3,
|
||||
0xd9, 0x71, 0x22, 0x50, 0x87, 0x37, 0x22, 0xa5, 0xa2, 0x9e, 0x60, 0x3c, 0x91, 0x8c, 0xc7, 0xb1,
|
||||
0xca, 0x72, 0x53, 0x13, 0x5d, 0xd7, 0x62, 0xf3, 0x78, 0x95, 0xd8, 0x63, 0x70, 0xfd, 0x70, 0x72,
|
||||
0x7c, 0x18, 0x04, 0x6a, 0x10, 0x67, 0x1d, 0x71, 0x34, 0x10, 0x98, 0xd1, 0x3a, 0x2c, 0xf2, 0x30,
|
||||
0x4c, 0x05, 0x62, 0x9d, 0x6c, 0x91, 0xe6, 0x72, 0xc7, 0x1c, 0xbd, 0x43, 0xb8, 0x52, 0xe6, 0x62,
|
||||
0xa2, 0x62, 0x14, 0xf4, 0x01, 0x40, 0x22, 0xd2, 0xbe, 0x44, 0x94, 0x2a, 0xce, 0xf3, 0x57, 0xda,
|
||||
0xae, 0x7f, 0xa6, 0x15, 0xfe, 0x41, 0x99, 0x84, 0x9d, 0x8a, 0xc2, 0x7b, 0x01, 0x6b, 0x55, 0x06,
|
||||
0x34, 0x10, 0x4f, 0x00, 0xa6, 0x2d, 0xd2, 0xbe, 0x3b, 0xc6, 0x77, 0xd2, 0x4f, 0xbf, 0xa8, 0x44,
|
||||
0xf7, 0xd3, 0x3f, 0xe0, 0x91, 0xd0, 0xda, 0x4e, 0x45, 0xe9, 0x7d, 0x21, 0x70, 0x75, 0xea, 0xad,
|
||||
0xa1, 0x9f, 0xc2, 0x12, 0xd7, 0x77, 0x75, 0xb2, 0x35, 0xdf, 0x5c, 0x69, 0xef, 0x59, 0x90, 0xf7,
|
||||
0x45, 0x2c, 0x50, 0xa2, 0x56, 0x57, 0x0b, 0x28, 0xd5, 0x74, 0x7f, 0x06, 0x73, 0x2e, 0xc7, 0x6c,
|
||||
0x5c, 0x88, 0x59, 0x60, 0xcc, 0x70, 0x3a, 0x50, 0xcf, 0xfb, 0xf0, 0x58, 0x22, 0xef, 0xf6, 0x44,
|
||||
0xf8, 0x4c, 0xa2, 0x19, 0x88, 0x77, 0x1f, 0xd6, 0x66, 0xaf, 0x75, 0x19, 0xdb, 0x70, 0x39, 0xd4,
|
||||
0xf7, 0x2f, 0x7b, 0x12, 0xb3, 0xbc, 0x96, 0xe5, 0xce, 0x6a, 0x58, 0x49, 0x6e, 0x7f, 0x9b, 0x87,
|
||||
0x85, 0xdc, 0x99, 0x7e, 0x20, 0xb0, 0xa8, 0x8b, 0xa1, 0x3b, 0x96, 0x7a, 0x2d, 0xbb, 0xe0, 0x78,
|
||||
0x96, 0xbc, 0x7f, 0x56, 0xc0, 0x6b, 0xbf, 0xff, 0xf3, 0x75, 0x97, 0x9c, 0xfc, 0xf8, 0xfd, 0x79,
|
||||
0xae, 0x41, 0x6f, 0xb3, 0xb3, 0xeb, 0x6a, 0xba, 0xc5, 0xde, 0xe8, 0x45, 0x7a, 0x4b, 0x4f, 0x08,
|
||||
0x2c, 0x99, 0xb1, 0xd0, 0xc6, 0x05, 0x30, 0x66, 0x29, 0x9c, 0xed, 0xf3, 0x69, 0xca, 0xe1, 0x7a,
|
||||
0xcd, 0x29, 0xce, 0x26, 0x5d, 0xff, 0x0f, 0x0e, 0xfd, 0x44, 0x60, 0xb5, 0xda, 0x58, 0x7a, 0xe7,
|
||||
0x3c, 0x10, 0xcb, 0x54, 0x1c, 0x1b, 0xb5, 0x6d, 0x4c, 0xde, 0xde, 0x14, 0xe8, 0x16, 0xbd, 0x69,
|
||||
0x01, 0xd2, 0xf3, 0xca, 0x67, 0xe8, 0x2c, 0xbc, 0x9b, 0x64, 0x3f, 0xba, 0xf7, 0x7d, 0xe4, 0x92,
|
||||
0xd3, 0x91, 0x4b, 0x7e, 0x8d, 0x5c, 0xf2, 0x71, 0xec, 0xd6, 0x4e, 0xc7, 0x6e, 0xed, 0xe7, 0xd8,
|
||||
0xad, 0x3d, 0xdf, 0x28, 0x0c, 0x30, 0x7c, 0xe5, 0x4b, 0xc5, 0x5e, 0x97, 0x46, 0xf9, 0x4f, 0xa1,
|
||||
0x7b, 0x29, 0xff, 0xb4, 0xef, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xab, 0xa8, 0x92, 0x5a, 0xad,
|
||||
0x04, 0x00, 0x00,
|
||||
// 516 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xc1, 0x6b, 0x13, 0x4f,
|
||||
0x14, 0xc7, 0x33, 0x2d, 0xbf, 0x5f, 0xdb, 0xd7, 0x8a, 0x3a, 0xf6, 0x10, 0xb6, 0xed, 0x5a, 0xb7,
|
||||
0xd8, 0x84, 0x5a, 0x76, 0x48, 0x04, 0x2f, 0x82, 0xa0, 0x88, 0xf5, 0xe0, 0xa1, 0xdd, 0xa3, 0x07,
|
||||
0x65, 0xb2, 0x3b, 0x84, 0xc1, 0x74, 0x67, 0xbb, 0x6f, 0x13, 0x2c, 0xe2, 0xa5, 0x27, 0xbd, 0x89,
|
||||
0xfe, 0x0d, 0x1e, 0x05, 0xff, 0x0c, 0x8f, 0x05, 0x2f, 0x1e, 0x25, 0x11, 0xfc, 0x37, 0xa4, 0xb3,
|
||||
0x33, 0x9b, 0x8d, 0x9d, 0xda, 0xe3, 0xcc, 0xbc, 0xef, 0xcb, 0xe7, 0xfb, 0xbe, 0x2f, 0x0b, 0x1b,
|
||||
0xb1, 0xc2, 0x43, 0x85, 0x2c, 0x96, 0x79, 0x3c, 0x94, 0x05, 0x1b, 0x75, 0xd8, 0xd1, 0x50, 0xe4,
|
||||
0xc7, 0x61, 0x96, 0xab, 0x42, 0xd1, 0xeb, 0xe5, 0x73, 0x68, 0x9e, 0xc3, 0x51, 0xc7, 0xdb, 0x31,
|
||||
0x8a, 0x1e, 0x47, 0x51, 0xd6, 0xb2, 0x51, 0xa7, 0x27, 0x0a, 0xde, 0x61, 0x19, 0xef, 0xcb, 0x94,
|
||||
0x17, 0x52, 0xa5, 0xa5, 0xdc, 0x73, 0x74, 0x2f, 0x8e, 0x33, 0x81, 0xe6, 0x79, 0xbd, 0xaf, 0x54,
|
||||
0x7f, 0x20, 0x18, 0xcf, 0x24, 0xe3, 0x69, 0xaa, 0x0a, 0xad, 0xb5, 0xaf, 0x6b, 0x46, 0x6c, 0x7f,
|
||||
0xa3, 0x0e, 0x16, 0x30, 0xb8, 0x71, 0x70, 0x76, 0x7c, 0x18, 0xc7, 0x6a, 0x98, 0x16, 0x91, 0x38,
|
||||
0x1a, 0x0a, 0x2c, 0x68, 0x13, 0x16, 0x78, 0x92, 0xe4, 0x02, 0xb1, 0x49, 0x36, 0x49, 0x7b, 0x29,
|
||||
0xb2, 0xc7, 0xe0, 0x00, 0xae, 0x56, 0xb5, 0x98, 0xa9, 0x14, 0x05, 0x7d, 0x00, 0x90, 0x89, 0xfc,
|
||||
0x50, 0x22, 0x4a, 0x95, 0xea, 0xfa, 0xe5, 0xae, 0x1f, 0x9e, 0x73, 0x1c, 0xee, 0x57, 0x45, 0x18,
|
||||
0xd5, 0x14, 0xc1, 0x0b, 0x58, 0xad, 0x33, 0xa0, 0x85, 0x78, 0x02, 0x30, 0x9d, 0x84, 0xe9, 0xbb,
|
||||
0x6d, 0xfb, 0x9e, 0x8d, 0x2d, 0x2c, 0x9d, 0x98, 0xb1, 0x85, 0xfb, 0xbc, 0x2f, 0x8c, 0x36, 0xaa,
|
||||
0x29, 0x83, 0xcf, 0x04, 0xae, 0x4d, 0x7b, 0x1b, 0xe8, 0xa7, 0xb0, 0xc8, 0xcd, 0x5d, 0x93, 0x6c,
|
||||
0xce, 0xb7, 0x97, 0xbb, 0xbb, 0x0e, 0xe4, 0x3d, 0x91, 0x0a, 0x94, 0x68, 0xd4, 0x75, 0x03, 0x95,
|
||||
0x9a, 0xee, 0xcd, 0x60, 0xce, 0x69, 0xcc, 0xd6, 0xa5, 0x98, 0x25, 0xc6, 0x0c, 0xa7, 0x07, 0x4d,
|
||||
0x3d, 0x87, 0xc7, 0x12, 0x79, 0x6f, 0x20, 0x92, 0x67, 0x12, 0x6d, 0x20, 0xc1, 0x7d, 0x58, 0x9d,
|
||||
0xbd, 0x36, 0x36, 0xb6, 0xe0, 0x4a, 0x62, 0xee, 0x5f, 0x0e, 0x24, 0x16, 0xda, 0xcb, 0x52, 0xb4,
|
||||
0x92, 0xd4, 0x8a, 0xbb, 0x5f, 0xe6, 0xe1, 0x3f, 0xdd, 0x99, 0xbe, 0x27, 0xb0, 0x60, 0xcc, 0xd0,
|
||||
0x6d, 0x87, 0x5f, 0xc7, 0x2e, 0x78, 0x81, 0xa3, 0xee, 0xaf, 0x15, 0x08, 0xba, 0xef, 0x7e, 0x7f,
|
||||
0xdd, 0x21, 0x27, 0xdf, 0x7f, 0x7d, 0x9a, 0x6b, 0xd1, 0xdb, 0xec, 0xfc, 0xba, 0xda, 0x69, 0xb1,
|
||||
0x37, 0x66, 0x91, 0xde, 0xd2, 0x13, 0x02, 0x8b, 0x36, 0x16, 0xda, 0xba, 0x04, 0xc6, 0x2e, 0x85,
|
||||
0xb7, 0x75, 0x31, 0x4d, 0x15, 0x6e, 0xd0, 0x9e, 0xe2, 0x6c, 0xd0, 0xb5, 0x7f, 0xe0, 0xd0, 0x8f,
|
||||
0x04, 0x56, 0xea, 0x83, 0xa5, 0x77, 0x2e, 0x02, 0x71, 0xa4, 0xe2, 0xb9, 0xa8, 0x5d, 0x31, 0x05,
|
||||
0xbb, 0x53, 0xa0, 0x5b, 0xf4, 0xa6, 0x03, 0xc8, 0xe4, 0xa5, 0x33, 0x7c, 0x74, 0xef, 0xdb, 0xd8,
|
||||
0x27, 0xa7, 0x63, 0x9f, 0xfc, 0x1c, 0xfb, 0xe4, 0xc3, 0xc4, 0x6f, 0x9c, 0x4e, 0xfc, 0xc6, 0x8f,
|
||||
0x89, 0xdf, 0x78, 0xbe, 0x5e, 0x2a, 0x31, 0x79, 0x15, 0x4a, 0xc5, 0x5e, 0x57, 0x1d, 0xf4, 0xd7,
|
||||
0xa0, 0xf7, 0xbf, 0xfe, 0x4f, 0xdf, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xdd, 0xdb, 0x03,
|
||||
0x8d, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user