From c61dbe40c8174ce7fe4788d8c94b7ad403ae7841 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 13:06:33 -0400 Subject: [PATCH 1/3] NONEVM-5349: add unregister receiver support --- .../receiver_registry/receiver_registry.go | 45 +++++ contracts/ccip/ccip/Move.lock | 14 +- .../ccip/ccip/sources/receiver_registry.move | 34 ++++ contracts/ccip/ccip/sources/state_object.move | 1 + .../tests/receiver_registry_mcms_test.move | 185 ++++++++++++++++++ .../ccip/ccip/tests/state_object_tests.move | 10 +- 6 files changed, 281 insertions(+), 8 deletions(-) create mode 100644 contracts/ccip/ccip/tests/receiver_registry_mcms_test.move diff --git a/bindings/generated/ccip/ccip/receiver_registry/receiver_registry.go b/bindings/generated/ccip/ccip/receiver_registry/receiver_registry.go index 0e596881d..3fb599e21 100644 --- a/bindings/generated/ccip/ccip/receiver_registry/receiver_registry.go +++ b/bindings/generated/ccip/ccip/receiver_registry/receiver_registry.go @@ -29,6 +29,7 @@ type IReceiverRegistry interface { GetReceiverConfig(ctx context.Context, opts *bind.CallOpts, ref bind.Object, receiverPackageId string) (*models.SuiTransactionBlockResponse, error) GetReceiverConfigFields(ctx context.Context, opts *bind.CallOpts, rc ReceiverConfig) (*models.SuiTransactionBlockResponse, error) GetReceiverInfo(ctx context.Context, opts *bind.CallOpts, ref bind.Object, receiverPackageId string) (*models.SuiTransactionBlockResponse, error) + McmsUnregisterReceiver(ctx context.Context, opts *bind.CallOpts, ref bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) DevInspect() IReceiverRegistryDevInspect Encoder() ReceiverRegistryEncoder Bound() bind.IBoundContract @@ -59,6 +60,8 @@ type ReceiverRegistryEncoder interface { GetReceiverConfigFieldsWithArgs(args ...any) (*bind.EncodedCall, error) GetReceiverInfo(ref bind.Object, receiverPackageId string) (*bind.EncodedCall, error) GetReceiverInfoWithArgs(args ...any) (*bind.EncodedCall, error) + McmsUnregisterReceiver(ref bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) + McmsUnregisterReceiverWithArgs(args ...any) (*bind.EncodedCall, error) } type ReceiverRegistryContract struct { @@ -200,6 +203,16 @@ func (c *ReceiverRegistryContract) GetReceiverInfo(ctx context.Context, opts *bi return c.ExecuteTransaction(ctx, opts, encoded) } +// McmsUnregisterReceiver executes the mcms_unregister_receiver Move function. +func (c *ReceiverRegistryContract) McmsUnregisterReceiver(ctx context.Context, opts *bind.CallOpts, ref bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { + encoded, err := c.receiverRegistryEncoder.McmsUnregisterReceiver(ref, registry, params) + if err != nil { + return nil, fmt.Errorf("failed to encode function call: %w", err) + } + + return c.ExecuteTransaction(ctx, opts, encoded) +} + // TypeAndVersion executes the type_and_version Move function using DevInspect to get return values. // // Returns: 0x1::string::String @@ -587,3 +600,35 @@ func (c receiverRegistryEncoder) GetReceiverInfoWithArgs(args ...any) (*bind.Enc "ascii::String", }) } + +// McmsUnregisterReceiver encodes a call to the mcms_unregister_receiver Move function. +func (c receiverRegistryEncoder) McmsUnregisterReceiver(ref bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { + typeArgsList := []string{} + typeParamsList := []string{} + return c.EncodeCallArgsWithGenerics("mcms_unregister_receiver", typeArgsList, typeParamsList, []string{ + "&mut CCIPObjectRef", + "&mut Registry", + "ExecutingCallbackParams", + }, []any{ + ref, + registry, + params, + }, nil) +} + +// McmsUnregisterReceiverWithArgs encodes a call to the mcms_unregister_receiver Move function using arbitrary arguments. +// This method allows passing both regular values and transaction.Argument values for PTB chaining. +func (c receiverRegistryEncoder) McmsUnregisterReceiverWithArgs(args ...any) (*bind.EncodedCall, error) { + expectedParams := []string{ + "&mut CCIPObjectRef", + "&mut Registry", + "ExecutingCallbackParams", + } + + if len(args) != len(expectedParams) { + return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) + } + typeArgsList := []string{} + typeParamsList := []string{} + return c.EncodeCallArgsWithGenerics("mcms_unregister_receiver", typeArgsList, typeParamsList, expectedParams, args, nil) +} diff --git a/contracts/ccip/ccip/Move.lock b/contracts/ccip/ccip/Move.lock index b1dc50ad8..fb994496c 100644 --- a/contracts/ccip/ccip/Move.lock +++ b/contracts/ccip/ccip/Move.lock @@ -5,13 +5,13 @@ version = 4 [pinned.testnet.MoveStdlib] -source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/move-stdlib", rev = "384b1c7ff289b32ed2664f29dc47dbc879fa43ee" } +source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/move-stdlib", rev = "718ae563a42fb4ba0d055588f81c704dcef58c25" } use_environment = "testnet" manifest_digest = "C4FE4C91DE74CBF223B2E380AE40F592177D21870DC2D7EB6227D2D694E05363" deps = {} [pinned.testnet.Sui] -source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "384b1c7ff289b32ed2664f29dc47dbc879fa43ee" } +source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "718ae563a42fb4ba0d055588f81c704dcef58c25" } use_environment = "testnet" manifest_digest = "7AFB66695545775FBFBB2D3078ADFD084244D5002392E837FDE21D9EA1C6D01C" deps = { MoveStdlib = "MoveStdlib" } @@ -19,10 +19,16 @@ deps = { MoveStdlib = "MoveStdlib" } [pinned.testnet.ccip] source = { root = true } use_environment = "testnet" -manifest_digest = "B41543A1928002B1ABE6F16D69A3C1BE6BCA4D7A4DB7D2F9048274EFE11ED724" -deps = { mcms = "mcms", std = "MoveStdlib", sui = "Sui" } +manifest_digest = "E5912E2FA12F49E878734EC73B1CAC461C88F1562C6C02B940082B986AE865FE" +deps = { fast_mcms = "mcms", mcms = "mcms_1", std = "MoveStdlib", sui = "Sui" } [pinned.testnet.mcms] +source = { local = "../../mcms/fast_mcms" } +use_environment = "testnet" +manifest_digest = "5745706258F61D6CE210904B3E6AE87A73CE9D31A6F93BE4718C442529332A87" +deps = { std = "MoveStdlib", sui = "Sui" } + +[pinned.testnet.mcms_1] source = { local = "../../mcms/mcms" } use_environment = "testnet" manifest_digest = "5745706258F61D6CE210904B3E6AE87A73CE9D31A6F93BE4718C442529332A87" diff --git a/contracts/ccip/ccip/sources/receiver_registry.move b/contracts/ccip/ccip/sources/receiver_registry.move index dc0337906..731846676 100644 --- a/contracts/ccip/ccip/sources/receiver_registry.move +++ b/contracts/ccip/ccip/sources/receiver_registry.move @@ -4,6 +4,8 @@ use ccip::ownable::OwnerCap; use ccip::publisher_wrapper::{Self, PublisherWrapper}; use ccip::state_object::{Self, CCIPObjectRef}; use ccip::upgrade_registry::verify_function_allowed; +use mcms::bcs_stream; +use mcms::mcms_registry::{Self, Registry, ExecutingCallbackParams}; use std::ascii; use std::string::{Self, String}; use std::type_name; @@ -35,6 +37,7 @@ const EAlreadyRegistered: u64 = 1; const EAlreadyInitialized: u64 = 2; const EUnknownReceiver: u64 = 3; const EInvalidOwnerCap: u64 = 4; +const EInvalidFunction: u64 = 5; const VERSION: u8 = 1; @@ -156,3 +159,34 @@ public fun get_receiver_info( (string::utf8(b""), ascii::string(b"")) } + +// ================================================================ +// | MCMS Functions | +// ================================================================ + +public fun mcms_unregister_receiver( + ref: &mut CCIPObjectRef, + registry: &mut Registry, + params: ExecutingCallbackParams, + ctx: &mut TxContext, +) { + let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< + state_object::McmsCallback, + OwnerCap, + >( + registry, + state_object::mcms_callback(), + params, + ); + assert!(function == string::utf8(b"unregister_receiver"), EInvalidFunction); + + let mut stream = bcs_stream::new(data); + bcs_stream::validate_obj_addrs( + vector[object::id_address(ref), object::id_address(owner_cap)], + &mut stream, + ); + let receiver_package_id = bcs_stream::deserialize_address(&mut stream); + bcs_stream::assert_is_consumed(&stream); + + unregister_receiver(ref, owner_cap, receiver_package_id, ctx); +} diff --git a/contracts/ccip/ccip/sources/state_object.move b/contracts/ccip/ccip/sources/state_object.move index 3e3838904..4200ace52 100644 --- a/contracts/ccip/ccip/sources/state_object.move +++ b/contracts/ccip/ccip/sources/state_object.move @@ -172,6 +172,7 @@ public fun execute_ownership_transfer_to_mcms( vector[ b"fee_quoter", b"rmn_remote", + b"receiver_registry", b"state_object", b"token_admin_registry", b"upgrade_registry", diff --git a/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move b/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move new file mode 100644 index 000000000..dec74fa42 --- /dev/null +++ b/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move @@ -0,0 +1,185 @@ +#[test_only] +#[allow(implicit_const_copy)] +module ccip::receiver_registry_mcms_test; + +use ccip::ownable::OwnerCap; +use ccip::publisher_wrapper; +use ccip::receiver_registry; +use ccip::state_object::{Self, CCIPObjectRef}; +use ccip::upgrade_registry; +use mcms::mcms_account; +use mcms::mcms_deployer; +use mcms::mcms_registry::{Self, Registry}; +use std::string; +use std::type_name; +use sui::address; +use sui::bcs; +use sui::package; +use sui::test_scenario::{Self as ts, Scenario}; + +const OWNER: address = @0x123; +const RECEIVER_REGISTRY_MODULE_NAME: vector = b"receiver_registry"; + +public struct RECEIVER_REGISTRY_MCMS_TEST has drop {} +public struct TestReceiverProof has drop, copy {} + +public struct Env { + scenario: Scenario, + ref: CCIPObjectRef, + registry: Registry, +} + +fun get_package_id_from_proof(): address { + let proof_tn = type_name::with_defining_ids(); + let address_str = type_name::address_string(&proof_tn); + address::from_ascii_bytes(&std::ascii::into_bytes(address_str)) +} + +fun setup(): Env { + let mut scenario = ts::begin(OWNER); + + { + let ctx = scenario.ctx(); + mcms_account::test_init(ctx); + mcms_registry::test_init(ctx); + mcms_deployer::test_init(ctx); + state_object::test_init(ctx); + }; + + scenario.next_tx(OWNER); + + let registry = ts::take_shared(&scenario); + let mut ref = ts::take_shared(&scenario); + let owner_cap = ts::take_from_sender(&scenario); + + upgrade_registry::initialize(&mut ref, &owner_cap, scenario.ctx()); + receiver_registry::initialize(&mut ref, &owner_cap, scenario.ctx()); + ts::return_to_address(OWNER, owner_cap); + + Env { + scenario, + ref, + registry, + } +} + +fun tear_down(env: Env) { + let Env { scenario, ref, registry } = env; + ts::return_shared(ref); + ts::return_shared(registry); + ts::end(scenario); +} + +fun register_test_receiver(ref: &mut CCIPObjectRef, ctx: &mut TxContext) { + let proof = TestReceiverProof {}; + let publisher = package::test_claim(RECEIVER_REGISTRY_MCMS_TEST {}, ctx); + let publisher_wrapper = publisher_wrapper::create(&publisher, proof); + receiver_registry::register_receiver(ref, publisher_wrapper, proof); + package::burn_publisher(publisher); +} + +fun transfer_ownership_to_mcms(env: &mut Env, owner_cap: OwnerCap) { + state_object::transfer_ownership( + &mut env.ref, + &owner_cap, + mcms_registry::get_multisig_address(), + env.scenario.ctx(), + ); + + env.scenario.next_tx(mcms_registry::get_multisig_address()); + state_object::accept_ownership(&mut env.ref, env.scenario.ctx()); + + state_object::execute_ownership_transfer_to_mcms( + &mut env.ref, + owner_cap, + &mut env.registry, + @mcms, + env.scenario.ctx(), + ); + + env.scenario.next_tx(OWNER); +} + +#[test] +public fun test_mcms_unregister_receiver() { + let mut env = setup(); + let package_id = get_package_id_from_proof(); + + register_test_receiver(&mut env.ref, env.scenario.ctx()); + assert!(receiver_registry::is_registered_receiver(&env.ref, package_id)); + + let owner_cap = ts::take_from_sender(&env.scenario); + transfer_ownership_to_mcms(&mut env, owner_cap); + + let owner_cap_address = mcms_registry::test_get_cap_address( + &env.registry, + @ccip.to_ascii_string(), + ); + + let mut data = vector[]; + data.append(bcs::to_bytes(&object::id_address(&env.ref))); + data.append(bcs::to_bytes(&owner_cap_address)); + data.append(bcs::to_bytes(&package_id)); + + let params = mcms_registry::test_create_executing_callback_params( + @ccip, + string::utf8(RECEIVER_REGISTRY_MODULE_NAME), + string::utf8(b"unregister_receiver"), + data, + x"0000000000000000000000000000000000000000000000000000000000000001", + 0, + 1, + ); + + receiver_registry::mcms_unregister_receiver( + &mut env.ref, + &mut env.registry, + params, + env.scenario.ctx(), + ); + + assert!(!receiver_registry::is_registered_receiver(&env.ref, package_id)); + + env.tear_down(); +} + +#[test] +#[expected_failure(abort_code = receiver_registry::EInvalidFunction)] +public fun test_mcms_unregister_receiver_wrong_function_name() { + let mut env = setup(); + let package_id = get_package_id_from_proof(); + + register_test_receiver(&mut env.ref, env.scenario.ctx()); + + let owner_cap = ts::take_from_sender(&env.scenario); + transfer_ownership_to_mcms(&mut env, owner_cap); + + let owner_cap_address = mcms_registry::test_get_cap_address( + &env.registry, + @ccip.to_ascii_string(), + ); + + let mut data = vector[]; + data.append(bcs::to_bytes(&object::id_address(&env.ref))); + data.append(bcs::to_bytes(&owner_cap_address)); + data.append(bcs::to_bytes(&package_id)); + + let params = mcms_registry::test_create_executing_callback_params( + @ccip, + string::utf8(RECEIVER_REGISTRY_MODULE_NAME), + string::utf8(b"register_receiver"), + data, + x"0000000000000000000000000000000000000000000000000000000000000001", + 0, + 1, + ); + + receiver_registry::mcms_unregister_receiver( + &mut env.ref, + &mut env.registry, + params, + env.scenario.ctx(), + ); + + env.tear_down(); +} diff --git a/contracts/ccip/ccip/tests/state_object_tests.move b/contracts/ccip/ccip/tests/state_object_tests.move index 7b37a046f..cfc35c54a 100644 --- a/contracts/ccip/ccip/tests/state_object_tests.move +++ b/contracts/ccip/ccip/tests/state_object_tests.move @@ -272,16 +272,18 @@ fun setup_with_mcms_ownership(): (Scenario, Registry, CCIPObjectRef) { fun test_mcms_add_allowed_modules_success() { let (mut scenario, mut registry, ref) = setup_with_mcms_ownership(); - // Verify initial allowed modules (should have fee_quoter, rmn_remote, state_object, token_admin_registry) + // Verify initial allowed modules let initial_modules = mcms_registry::get_allowed_modules( ®istry, address::to_ascii_string(@ccip), ); assert!(initial_modules.contains(&b"fee_quoter"), 0); assert!(initial_modules.contains(&b"rmn_remote"), 1); - assert!(initial_modules.contains(&b"state_object"), 2); - assert!(initial_modules.contains(&b"token_admin_registry"), 3); - assert!(!initial_modules.contains(&b"nonce_manager"), 4); // Should not exist yet + assert!(initial_modules.contains(&b"receiver_registry"), 2); + assert!(initial_modules.contains(&b"state_object"), 3); + assert!(initial_modules.contains(&b"token_admin_registry"), 4); + assert!(initial_modules.contains(&b"upgrade_registry"), 5); + assert!(!initial_modules.contains(&b"nonce_manager"), 6); // Should not exist yet // Prepare data for mcms_add_allowed_modules // Data format: [registry_address][vector> of module names] From e6f726e1bf1807443ac035843fee393beea98b4a Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 13:14:44 -0400 Subject: [PATCH 2/3] fix --- .github/workflows/pull-request-develop.yml | 4 +++ .../tests/receiver_registry_mcms_test.move | 2 ++ go.md | 29 +++++++++++++++---- go.mod | 4 +-- go.sum | 4 +++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pull-request-develop.yml b/.github/workflows/pull-request-develop.yml index d487981f3..298a420a2 100644 --- a/.github/workflows/pull-request-develop.yml +++ b/.github/workflows/pull-request-develop.yml @@ -174,6 +174,10 @@ jobs: - name: Setup Nix uses: smartcontractkit/.github/actions/setup-nix@01d931b0455a754d12e7143cc54a5a3521a8f6f6 # setup-nix@0.3.2 + - name: Install latest gomods and modgraph + run: | + nix develop -c go get -tool github.com/jmank88/gomods@latest github.com/jmank88/modgraph@latest + - name: Ensure modules are tidy run: | nix develop -c go tool gomods tidy diff --git a/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move b/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move index dec74fa42..11572247a 100644 --- a/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move +++ b/contracts/ccip/ccip/tests/receiver_registry_mcms_test.move @@ -56,6 +56,8 @@ fun setup(): Env { receiver_registry::initialize(&mut ref, &owner_cap, scenario.ctx()); ts::return_to_address(OWNER, owner_cap); + scenario.next_tx(OWNER); + Env { scenario, ref, diff --git a/go.md b/go.md index 3e9180cc6..18b2e3fb4 100644 --- a/go.md +++ b/go.md @@ -81,7 +81,25 @@ flowchart LR click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink-aptos --> chainlink-common click chainlink-aptos href "https://github.com/smartcontractkit/chainlink-aptos" - chainlink-canton + chainlink-canton --> ccip-contract-examples/chains/evm + chainlink-canton --> chainlink-ccip/deployment + chainlink-canton --> chainlink-ccv + chainlink-canton --> chainlink-ccv/build/devenv + chainlink-canton --> chainlink-ccv/deployment + chainlink-canton --> chainlink-common/keystore + chainlink-canton --> chainlink-framework/multinode + chainlink-canton --> chainlink-protos/chainlink-ccv/committee-verifier + chainlink-canton --> chainlink-protos/chainlink-ccv/heartbeat + chainlink-canton --> chainlink-protos/chainlink-ccv/message-discovery + chainlink-canton --> chainlink-protos/chainlink-ccv/message-rules + chainlink-canton --> chainlink-protos/chainlink-ccv/verifier + chainlink-canton --> chainlink-protos/orchestrator + chainlink-canton --> chainlink-protos/svr + chainlink-canton --> chainlink-testing-framework/lib/grafana + chainlink-canton --> chainlink-testing-framework/wasp + chainlink-canton --> chainlink/deployment + chainlink-canton --> chainlink/v2 + chainlink-canton --> wsrpc click chainlink-canton href "https://github.com/smartcontractkit/chainlink-canton" chainlink-ccip --> chainlink-common chainlink-ccip --> chainlink-protos/rmn/v1.6/go @@ -96,9 +114,6 @@ flowchart LR chainlink-ccip/deployment --> chainlink-evm chainlink-ccip/deployment --> chainlink-evm/gethwrappers chainlink-ccip/deployment --> chainlink-framework/chains - chainlink-ccip/deployment --> chainlink-protos/op-catalog - chainlink-ccip/deployment --> chainlink-testing-framework/seth - chainlink-ccip/deployment --> mcms click chainlink-ccip/deployment href "https://github.com/smartcontractkit/chainlink-ccip" chainlink-ccv click chainlink-ccv href "https://github.com/smartcontractkit/chainlink-ccv" @@ -125,7 +140,11 @@ flowchart LR click chainlink-common/pkg/monitoring href "https://github.com/smartcontractkit/chainlink-common" chainlink-common/pkg/values click chainlink-common/pkg/values href "https://github.com/smartcontractkit/chainlink-common" - chainlink-deployments-framework + chainlink-deployments-framework --> ccip-owner-contracts + chainlink-deployments-framework --> chainlink-ccip/chains/evm + chainlink-deployments-framework --> chainlink-protos/op-catalog + chainlink-deployments-framework --> chainlink-testing-framework/seth + chainlink-deployments-framework --> mcms click chainlink-deployments-framework href "https://github.com/smartcontractkit/chainlink-deployments-framework" chainlink-evm click chainlink-evm href "https://github.com/smartcontractkit/chainlink-evm" diff --git a/go.mod b/go.mod index b9a59128e..7a154b86e 100644 --- a/go.mod +++ b/go.mod @@ -84,8 +84,8 @@ require ( github.com/jackc/pgx/v5 v5.9.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/copier v0.4.0 // indirect - github.com/jmank88/gomods v0.1.6 // indirect - github.com/jmank88/modgraph v0.1.1 // indirect + github.com/jmank88/gomods v0.1.7 // indirect + github.com/jmank88/modgraph v0.1.4 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index f4acbd529..e7b5b1be5 100644 --- a/go.sum +++ b/go.sum @@ -195,8 +195,12 @@ github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmank88/gomods v0.1.6 h1:HNHM9x2QPdF7R72pm83MZpori5AlPiXiukTdLqrUJYE= github.com/jmank88/gomods v0.1.6/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= +github.com/jmank88/gomods v0.1.7 h1:NG0ht+Z2wBO1EX6jn8cHa4iLQVqCKwmw426F4T6SBDo= +github.com/jmank88/gomods v0.1.7/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= github.com/jmank88/modgraph v0.1.1 h1:Lz9XlGbsb//zsHRDPq+fbU28NaSgUwUY/1PjbOMLnew= github.com/jmank88/modgraph v0.1.1/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= +github.com/jmank88/modgraph v0.1.4 h1:eNLt3l47NoyySHkgmcQeG/s9d5I2B5S7LQHpvSBU7Ks= +github.com/jmank88/modgraph v0.1.4/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= From 2f3f0b3ed2251e47c574af973e6c4f2b2396295c Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 13:17:48 -0400 Subject: [PATCH 3/3] go mod --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index e7b5b1be5..9b2e474ca 100644 --- a/go.sum +++ b/go.sum @@ -193,12 +193,8 @@ github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5Xum github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= -github.com/jmank88/gomods v0.1.6 h1:HNHM9x2QPdF7R72pm83MZpori5AlPiXiukTdLqrUJYE= -github.com/jmank88/gomods v0.1.6/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= github.com/jmank88/gomods v0.1.7 h1:NG0ht+Z2wBO1EX6jn8cHa4iLQVqCKwmw426F4T6SBDo= github.com/jmank88/gomods v0.1.7/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= -github.com/jmank88/modgraph v0.1.1 h1:Lz9XlGbsb//zsHRDPq+fbU28NaSgUwUY/1PjbOMLnew= -github.com/jmank88/modgraph v0.1.1/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmank88/modgraph v0.1.4 h1:eNLt3l47NoyySHkgmcQeG/s9d5I2B5S7LQHpvSBU7Ks= github.com/jmank88/modgraph v0.1.4/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=