From 8c63dae68284cb5426cb9cc07967e367c7d627cd Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Thu, 19 Sep 2024 19:29:12 +0800 Subject: [PATCH] feat: accomodate ADR-25 to add jailed status to fp instance (#56) Partially closes #5 by introducing `jailed` status to the fp instance. The jailing status can be found in two ways: 1. The status update loop periodically checks whether the fp is slashed or jailed 2. Upon `ErrFpAlreadyJailed` error when submitting finality signature Once jailing is detected, the status of the fp instance will be set to `jailed` and terminated. --- clientcontroller/babylon.go | 8 +- clientcontroller/interface.go | 4 +- clientcontroller/retry_utils.go | 1 + eotsmanager/proto/eotsmanager.pb.go | 2 +- .../proto/finality_providers.pb.go | 104 +++++++++--------- .../proto/finality_providers.proto | 2 + finality-provider/service/fp_instance.go | 9 +- finality-provider/service/fp_manager.go | 31 +++++- finality-provider/service/fp_manager_test.go | 20 +++- go.mod | 3 +- go.sum | 6 +- testutil/mocks/babylon.go | 17 +-- tools/go.mod | 4 +- tools/go.sum | 7 +- 14 files changed, 126 insertions(+), 92 deletions(-) diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index 5468994a..ff89ce8d 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -257,16 +257,14 @@ func (bc *BabylonController) SubmitBatchFinalitySigs( return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil } -func (bc *BabylonController) QueryFinalityProviderSlashed(fpPk *btcec.PublicKey) (bool, error) { +func (bc *BabylonController) QueryFinalityProviderSlashedOrJailed(fpPk *btcec.PublicKey) (slashed bool, jailed bool, err error) { fpPubKey := bbntypes.NewBIP340PubKeyFromBTCPK(fpPk) res, err := bc.bbnClient.QueryClient.FinalityProvider(fpPubKey.MarshalHex()) if err != nil { - return false, fmt.Errorf("failed to query the finality provider %s: %v", fpPubKey.MarshalHex(), err) + return false, false, fmt.Errorf("failed to query the finality provider %s: %v", fpPubKey.MarshalHex(), err) } - slashed := res.FinalityProvider.SlashedBtcHeight > 0 - - return slashed, nil + return res.FinalityProvider.SlashedBtcHeight > 0, res.FinalityProvider.Jailed, nil } // QueryFinalityProviderVotingPower queries the voting power of the finality provider at a given height diff --git a/clientcontroller/interface.go b/clientcontroller/interface.go index a7100068..c1e210a5 100644 --- a/clientcontroller/interface.go +++ b/clientcontroller/interface.go @@ -45,8 +45,8 @@ type ClientController interface { // QueryFinalityProviderVotingPower queries the voting power of the finality provider at a given height QueryFinalityProviderVotingPower(fpPk *btcec.PublicKey, blockHeight uint64) (uint64, error) - // QueryFinalityProviderSlashed queries if the finality provider is slashed - QueryFinalityProviderSlashed(fpPk *btcec.PublicKey) (bool, error) + // QueryFinalityProviderSlashedOrJailed queries if the finality provider is slashed or jailed + QueryFinalityProviderSlashedOrJailed(fpPk *btcec.PublicKey) (slashed bool, jailed bool, err error) // QueryLatestFinalizedBlocks returns the latest finalized blocks QueryLatestFinalizedBlocks(count uint64) ([]*types.BlockInfo, error) diff --git a/clientcontroller/retry_utils.go b/clientcontroller/retry_utils.go index a0eb1a4c..10813622 100644 --- a/clientcontroller/retry_utils.go +++ b/clientcontroller/retry_utils.go @@ -18,6 +18,7 @@ var unrecoverableErrors = []*sdkErr.Error{ finalitytypes.ErrPubRandNotFound, finalitytypes.ErrTooFewPubRand, btcstakingtypes.ErrFpAlreadySlashed, + btcstakingtypes.ErrFpAlreadyJailed, } // IsUnrecoverable returns true when the error is in the unrecoverableErrors list diff --git a/eotsmanager/proto/eotsmanager.pb.go b/eotsmanager/proto/eotsmanager.pb.go index 50c63822..eaf5ac07 100644 --- a/eotsmanager/proto/eotsmanager.pb.go +++ b/eotsmanager/proto/eotsmanager.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.31.0 // protoc (unknown) // source: eotsmanager.proto diff --git a/finality-provider/proto/finality_providers.pb.go b/finality-provider/proto/finality_providers.pb.go index 760750c9..fe2b59f3 100644 --- a/finality-provider/proto/finality_providers.pb.go +++ b/finality-provider/proto/finality_providers.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.31.0 // protoc (unknown) // source: finality_providers.proto @@ -52,6 +52,8 @@ const ( FinalityProviderStatus_INACTIVE FinalityProviderStatus = 3 // SLASHED defines a finality provider that has been slashed FinalityProviderStatus_SLASHED FinalityProviderStatus = 4 + // JAILED defines a finality provider that has been jailed + FinalityProviderStatus_JAILED FinalityProviderStatus = 5 ) // Enum value maps for FinalityProviderStatus. @@ -62,6 +64,7 @@ var ( 2: "ACTIVE", 3: "INACTIVE", 4: "SLASHED", + 5: "JAILED", } FinalityProviderStatus_value = map[string]int32{ "CREATED": 0, @@ -69,6 +72,7 @@ var ( "ACTIVE": 2, "INACTIVE": 3, "SLASHED": 4, + "JAILED": 5, } ) @@ -1458,7 +1462,7 @@ var file_finality_providers_proto_rawDesc = []byte{ 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x2a, 0xa6, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x75, 0x72, 0x65, 0x2a, 0xbe, 0x01, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x45, 0x47, 0x49, @@ -1468,56 +1472,58 @@ var file_finality_providers_proto_rawDesc = []byte{ 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x53, - 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x32, 0xc0, 0x05, 0x0a, - 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, - 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x4a, 0x41, 0x49, 0x4c, 0x45, 0x44, + 0x10, 0x05, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x4a, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x1a, 0x04, + 0x88, 0xa3, 0x1e, 0x00, 0x32, 0xc0, 0x05, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x24, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x18, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, - 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x17, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, - 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, - 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, - 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x66, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x15, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, + 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, + 0x17, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x6c, 0x61, 0x62, + 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/finality-provider/proto/finality_providers.proto b/finality-provider/proto/finality_providers.proto index ac4a6a64..66083d1a 100644 --- a/finality-provider/proto/finality_providers.proto +++ b/finality-provider/proto/finality_providers.proto @@ -219,6 +219,8 @@ enum FinalityProviderStatus { INACTIVE = 3 [(gogoproto.enumvalue_customname) = "INACTIVE"]; // SLASHED defines a finality provider that has been slashed SLASHED = 4 [(gogoproto.enumvalue_customname) = "SLASHED"]; + // JAILED defines a finality provider that has been jailed + JAILED = 5 [(gogoproto.enumvalue_customname) = "JAILED"]; } message SignMessageFromChainKeyRequest { diff --git a/finality-provider/service/fp_instance.go b/finality-provider/service/fp_instance.go index e5b30ba7..4d0731a2 100644 --- a/finality-provider/service/fp_instance.go +++ b/finality-provider/service/fp_instance.go @@ -907,14 +907,15 @@ func (fp *FinalityProviderInstance) GetVotingPowerWithRetry(height uint64) (uint return power, nil } -func (fp *FinalityProviderInstance) GetFinalityProviderSlashedWithRetry() (bool, error) { +func (fp *FinalityProviderInstance) GetFinalityProviderSlashedOrJailedWithRetry() (bool, bool, error) { var ( slashed bool + jailed bool err error ) if err := retry.Do(func() error { - slashed, err = fp.cc.QueryFinalityProviderSlashed(fp.GetBtcPk()) + slashed, jailed, err = fp.cc.QueryFinalityProviderSlashedOrJailed(fp.GetBtcPk()) if err != nil { return err } @@ -927,8 +928,8 @@ func (fp *FinalityProviderInstance) GetFinalityProviderSlashedWithRetry() (bool, zap.Error(err), ) })); err != nil { - return false, err + return false, false, err } - return slashed, nil + return slashed, jailed, nil } diff --git a/finality-provider/service/fp_manager.go b/finality-provider/service/fp_manager.go index f5d5f18b..12a39d3f 100644 --- a/finality-provider/service/fp_manager.go +++ b/finality-provider/service/fp_manager.go @@ -106,6 +106,12 @@ func (fpm *FinalityProviderManager) monitorCriticalErr() { zap.String("pk", criticalErr.fpBtcPk.MarshalHex())) continue } + if strings.Contains(criticalErr.err.Error(), btcstakingtypes.ErrFpAlreadyJailed.Error()) { + fpm.setFinalityProviderJailed(fpi) + fpm.logger.Debug("the finality-provider has been jailed", + zap.String("pk", criticalErr.fpBtcPk.MarshalHex())) + continue + } fpm.logger.Fatal(instanceTerminatingMsg, zap.String("pk", criticalErr.fpBtcPk.MarshalHex()), zap.Error(criticalErr.err)) case <-fpm.quit: @@ -166,25 +172,35 @@ func (fpm *FinalityProviderManager) monitorStatusUpdate() { } continue } - slashed, err := fpi.GetFinalityProviderSlashedWithRetry() + slashed, jailed, err := fpi.GetFinalityProviderSlashedOrJailedWithRetry() if err != nil { fpm.logger.Debug( - "failed to get the slashed height", + "failed to get the slashed or jailed status", zap.String("fp_btc_pk", fpi.GetBtcPkHex()), zap.Error(err), ) continue } - // power == 0 and slashed == true, set status to SLASHED and stop and remove the finality-provider instance + // power == 0 and slashed == true, set status to SLASHED, stop, and remove the finality-provider instance if slashed { fpm.setFinalityProviderSlashed(fpi) - fpm.logger.Debug( + fpm.logger.Warn( "the finality-provider is slashed", zap.String("fp_btc_pk", fpi.GetBtcPkHex()), zap.String("old_status", oldStatus.String()), ) continue } + // power == 0 and jailed == true, set status to JAILED, stop, and remove the finality-provider instance + if jailed { + fpm.setFinalityProviderJailed(fpi) + fpm.logger.Warn( + "the finality-provider is jailed", + zap.String("fp_btc_pk", fpi.GetBtcPkHex()), + zap.String("old_status", oldStatus.String()), + ) + continue + } // power == 0 and slashed_height == 0, change to INACTIVE if the current status is ACTIVE if oldStatus == proto.FinalityProviderStatus_ACTIVE { fpi.MustSetStatus(proto.FinalityProviderStatus_INACTIVE) @@ -208,6 +224,13 @@ func (fpm *FinalityProviderManager) setFinalityProviderSlashed(fpi *FinalityProv } } +func (fpm *FinalityProviderManager) setFinalityProviderJailed(fpi *FinalityProviderInstance) { + fpi.MustSetStatus(proto.FinalityProviderStatus_JAILED) + if err := fpm.removeFinalityProviderInstance(fpi.GetBtcPkBIP340()); err != nil { + panic(fmt.Errorf("failed to terminate a jailed finality-provider %s: %w", fpi.GetBtcPkHex(), err)) + } +} + func (fpm *FinalityProviderManager) StartFinalityProvider(fpPk *bbntypes.BIP340PubKey, passphrase string) error { if !fpm.isStarted.Load() { fpm.isStarted.Store(true) diff --git a/finality-provider/service/fp_manager_test.go b/finality-provider/service/fp_manager_test.go index 5c77be61..71a02627 100644 --- a/finality-provider/service/fp_manager_test.go +++ b/finality-provider/service/fp_manager_test.go @@ -30,7 +30,7 @@ import ( ) var ( - eventuallyWaitTimeOut = 1 * time.Second + eventuallyWaitTimeOut = 5 * time.Second eventuallyPollTime = 10 * time.Millisecond ) @@ -61,9 +61,17 @@ func FuzzStatusUpdate(f *testing.F) { votingPower := uint64(r.Intn(2)) mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), currentHeight).Return(votingPower, nil).AnyTimes() mockClientController.EXPECT().SubmitFinalitySig(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.TxResponse{TxHash: ""}, nil).AnyTimes() - var slashedHeight uint64 + var isSlashedOrJailed int if votingPower == 0 { - mockClientController.EXPECT().QueryFinalityProviderSlashed(gomock.Any()).Return(true, nil).AnyTimes() + // 0 means is slashed, 1 means is jailed, 2 means neither slashed nor jailed + isSlashedOrJailed = r.Intn(3) + if isSlashedOrJailed == 0 { + mockClientController.EXPECT().QueryFinalityProviderSlashedOrJailed(gomock.Any()).Return(true, false, nil).AnyTimes() + } else if isSlashedOrJailed == 1 { + mockClientController.EXPECT().QueryFinalityProviderSlashedOrJailed(gomock.Any()).Return(false, true, nil).AnyTimes() + } else { + mockClientController.EXPECT().QueryFinalityProviderSlashedOrJailed(gomock.Any()).Return(false, false, nil).AnyTimes() + } } err := vm.StartFinalityProvider(fpPk, passphrase) @@ -76,9 +84,11 @@ func FuzzStatusUpdate(f *testing.F) { if votingPower > 0 { waitForStatus(t, fpIns, proto.FinalityProviderStatus_ACTIVE) } else { - if slashedHeight == 0 && fpIns.GetStatus() == proto.FinalityProviderStatus_ACTIVE { + if isSlashedOrJailed == 2 && fpIns.GetStatus() == proto.FinalityProviderStatus_ACTIVE { waitForStatus(t, fpIns, proto.FinalityProviderStatus_INACTIVE) - } else if slashedHeight > 0 { + } else if isSlashedOrJailed == 1 { + waitForStatus(t, fpIns, proto.FinalityProviderStatus_JAILED) + } else if isSlashedOrJailed == 0 { waitForStatus(t, fpIns, proto.FinalityProviderStatus_SLASHED) } } diff --git a/go.mod b/go.mod index 349600b5..dfc9c8ad 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/avast/retry-go/v4 v4.5.1 - github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177 + github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b github.com/btcsuite/btcd v0.24.2 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 @@ -108,7 +108,6 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v24.0.9+incompatible // indirect github.com/dsnet/compress v0.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect diff --git a/go.sum b/go.sum index 83df9ab9..7deb5272 100644 --- a/go.sum +++ b/go.sum @@ -281,8 +281,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177 h1:rcbSkxPZVl5AdWt40prUUzj7Rpuv3jD6PvlLh1dQ0DM= -github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177/go.mod h1:9VUUAwVaalXiDdPZT65SPoawKWpp6ple6tBr8Vw0NI8= +github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b h1:2PU+equYzx7Hw1Tl2uO800R36suqXjnYl0XPLyNeSA0= +github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b/go.mod h1:ZOrTde9vs2xoqGTFw4xhupu2CMulnpywiuk0eh4kPOw= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -475,8 +475,6 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= -github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= diff --git a/testutil/mocks/babylon.go b/testutil/mocks/babylon.go index 09210f01..31be816d 100644 --- a/testutil/mocks/babylon.go +++ b/testutil/mocks/babylon.go @@ -127,19 +127,20 @@ func (mr *MockClientControllerMockRecorder) QueryBlocks(startHeight, endHeight, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBlocks", reflect.TypeOf((*MockClientController)(nil).QueryBlocks), startHeight, endHeight, limit) } -// QueryFinalityProviderSlashed mocks base method. -func (m *MockClientController) QueryFinalityProviderSlashed(fpPk *btcec.PublicKey) (bool, error) { +// QueryFinalityProviderSlashedOrJailed mocks base method. +func (m *MockClientController) QueryFinalityProviderSlashedOrJailed(fpPk *btcec.PublicKey) (bool, bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryFinalityProviderSlashed", fpPk) + ret := m.ctrl.Call(m, "QueryFinalityProviderSlashedOrJailed", fpPk) ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// QueryFinalityProviderSlashed indicates an expected call of QueryFinalityProviderSlashed. -func (mr *MockClientControllerMockRecorder) QueryFinalityProviderSlashed(fpPk interface{}) *gomock.Call { +// QueryFinalityProviderSlashedOrJailed indicates an expected call of QueryFinalityProviderSlashedOrJailed. +func (mr *MockClientControllerMockRecorder) QueryFinalityProviderSlashedOrJailed(fpPk interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFinalityProviderSlashed", reflect.TypeOf((*MockClientController)(nil).QueryFinalityProviderSlashed), fpPk) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryFinalityProviderSlashedOrJailed", reflect.TypeOf((*MockClientController)(nil).QueryFinalityProviderSlashedOrJailed), fpPk) } // QueryFinalityProviderVotingPower mocks base method. diff --git a/tools/go.mod b/tools/go.mod index 2ce0cca6..18d48e7e 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -4,7 +4,7 @@ go 1.21 toolchain go1.21.4 -require github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177 +require github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b require ( cloud.google.com/go v0.112.0 // indirect @@ -83,7 +83,6 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v24.0.9+incompatible // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect @@ -171,7 +170,6 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index a0af02a0..68f96a22 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -268,8 +268,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177 h1:rcbSkxPZVl5AdWt40prUUzj7Rpuv3jD6PvlLh1dQ0DM= -github.com/babylonlabs-io/babylon v0.9.3-0.20240904154239-00330e49b177/go.mod h1:9VUUAwVaalXiDdPZT65SPoawKWpp6ple6tBr8Vw0NI8= +github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b h1:2PU+equYzx7Hw1Tl2uO800R36suqXjnYl0XPLyNeSA0= +github.com/babylonlabs-io/babylon v0.9.3-0.20240919093955-dec7fa8fff9b/go.mod h1:ZOrTde9vs2xoqGTFw4xhupu2CMulnpywiuk0eh4kPOw= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -443,8 +443,6 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= -github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -1389,7 +1387,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=