diff --git a/accounts/manager.go b/accounts/manager.go index a2218e54dd..ebf7bbd62c 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -18,6 +18,7 @@ package accounts import ( "reflect" + "slices" "sort" "sync" @@ -254,13 +255,12 @@ func merge(slice []Wallet, wallets ...Wallet) []Wallet { // drop is the counterpart of merge, which looks up wallets from within the sorted // cache and removes the ones specified. func drop(slice []Wallet, wallets ...Wallet) []Wallet { - for _, wallet := range wallets { - n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) - if n == len(slice) { - // Wallet not found, may happen during startup - continue - } - slice = append(slice[:n], slice[n+1:]...) + remove := make(map[URL]struct{}, len(wallets)) + for _, w := range wallets { + remove[w.URL()] = struct{}{} } - return slice + return slices.DeleteFunc(slice, func(w Wallet) bool { + _, ok := remove[w.URL()] + return ok + }) } diff --git a/accounts/manager_test.go b/accounts/manager_test.go new file mode 100644 index 0000000000..6727be156e --- /dev/null +++ b/accounts/manager_test.go @@ -0,0 +1,47 @@ +// Copyright 2026 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package accounts + +import "testing" + +type managerTestWallet struct { + Wallet + url URL +} + +func (w managerTestWallet) URL() URL { + return w.url +} + +func TestDropMissingWallet(t *testing.T) { + t.Parallel() + + wallets := []Wallet{ + managerTestWallet{url: URL{Scheme: "test", Path: "a"}}, + managerTestWallet{url: URL{Scheme: "test", Path: "c"}}, + } + dropped := drop(wallets, managerTestWallet{url: URL{Scheme: "test", Path: "b"}}) + + if len(dropped) != len(wallets) { + t.Fatalf("drop removed wallet for missing URL: got %d wallets, want %d", len(dropped), len(wallets)) + } + for i := range dropped { + if got, want := dropped[i].URL(), wallets[i].URL(); got != want { + t.Fatalf("wallet %d mismatch: got %v, want %v", i, got, want) + } + } +}