diff --git a/waddrmgr/address.go b/waddrmgr/address.go index cf58531e83..c19fcd16a7 100644 --- a/waddrmgr/address.go +++ b/waddrmgr/address.go @@ -536,6 +536,14 @@ func newManagedAddressFromExtKey(s *ScopedKeyManager, return managedAddr, nil } +// clearTextScriptSetter is a non-exported interface to identify script types +// that allow their clear text script to be set. +type clearTextScriptSetter interface { + // setClearText sets the unencrypted script on the struct after + // unlocking/decrypting it. + setClearTextScript([]byte) +} + // baseScriptAddress represents the common fields of a pay-to-script-hash and // a pay-to-witness-script-hash address. type baseScriptAddress struct { @@ -547,6 +555,8 @@ type baseScriptAddress struct { scriptMutex sync.Mutex } +var _ clearTextScriptSetter = (*baseScriptAddress)(nil) + // unlock decrypts and stores the associated script. It will fail if the key is // invalid or the encrypted script is not available. The returned clear text // script will always be a copy that may be safely used by the caller without @@ -605,6 +615,13 @@ func (a *baseScriptAddress) Internal() bool { return false } +// setClearText sets the unencrypted script on the struct after unlocking/ +// decrypting it. +func (a *baseScriptAddress) setClearTextScript(script []byte) { + a.scriptClearText = make([]byte, len(script)) + copy(a.scriptClearText, script) +} + // scriptAddress represents a pay-to-script-hash address. type scriptAddress struct { baseScriptAddress diff --git a/waddrmgr/scoped_manager.go b/waddrmgr/scoped_manager.go index 6d7f435cde..ab3b67e9a2 100644 --- a/waddrmgr/scoped_manager.go +++ b/waddrmgr/scoped_manager.go @@ -2215,38 +2215,29 @@ func (s *ScopedKeyManager) importScriptAddress(ns walletdb.ReadWriteBucket, // when not a watching-only address manager, make a copy of the script // since it will be cleared on lock and the script the caller passed // should not be cleared out from under the caller. - var ( - managedAddr ManagedScriptAddress - baseScriptAddr *baseScriptAddress - ) + var managedAddr ManagedScriptAddress switch addrType { case WitnessScript: - witnessAddr, err := newWitnessScriptAddress( + managedAddr, err = newWitnessScriptAddress( s, ImportedAddrAccount, scriptIdent, encryptedScript, witnessVersion, isSecretScript, ) - if err != nil { - return nil, err - } - managedAddr = witnessAddr - baseScriptAddr = &witnessAddr.baseScriptAddress default: - scriptAddr, err := newScriptAddress( + managedAddr, err = newScriptAddress( s, ImportedAddrAccount, scriptIdent, encryptedScript, ) - if err != nil { - return nil, err - } - managedAddr = scriptAddr - baseScriptAddr = &scriptAddr.baseScriptAddress + } + if err != nil { + return nil, err } // Even if the script is secret, we are currently unlocked, so we keep a // clear text copy of the script around to avoid decrypting it on each // access. - baseScriptAddr.scriptClearText = make([]byte, len(script)) - copy(baseScriptAddr.scriptClearText, script) + if cts, ok := managedAddr.(clearTextScriptSetter); ok { + cts.setClearTextScript(script) + } // Add the new managed address to the cache of recent addresses and // return it.