-
Notifications
You must be signed in to change notification settings - Fork 18
EVM: Split signer from account #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 47 commits
5805196
8a4dc0c
e04a862
4c77e8c
4f18ce8
2bd8427
c00a22e
fc31010
6dbfe99
5af6f0a
3a6b289
1734267
bb9f608
ccdcfb9
c4a879f
db2ff81
f921284
f9fb077
d937ab8
123e995
b2d6660
d03a102
b901da8
9372233
8c12540
cbc2d6c
84b8cb1
86d0061
4b03dc9
997cbb5
9f94876
cefe0a9
a213e11
6a378b8
bf11299
3a041e0
65576ed
432aac7
e615962
109ba85
d979205
eb47d2c
d81a6d0
aeb52e3
64ea4b9
03cba9d
13cf4ac
e4a0235
3a2e0cd
cfe141e
a264337
0dcd6a8
49a3f3e
74b3ea9
6bc4b85
815d022
853525f
79c41bd
ad224c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| node_modules | ||
| coverage | ||
| .vscode | ||
| .DS_Store | ||
| .vscode |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,8 +70,9 @@ export default class MemorySafeSigningKey extends SigningKey { | |
| } | ||
|
|
||
| dispose () { | ||
| sodium_memzero(this._privateKeyBuffer) | ||
|
|
||
| this._privateKeyBuffer = undefined | ||
| if (this._privateKeyBuffer) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need for the 'dispose' method to be idempotent. By definition, after disposing an object users should expect all methods to have undefined behavior which basically includes anything. We should just guarantee that such undefined behavior doesn't include any unsafe operations but since the private key is not available anymore this is not a possible scenario. These changes are not a mistake but we can safely revert them.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd keep the guard, and I don't think this is about post-dispose undefined behavior... it's about disposal itself being safe to run from multiple owners. WalletManager.dispose() disposes all accounts (each of which disposes its signer) and then loops over the registered signers disposing them again. For a named non-derivable signer, the account's signer is the registered signer object, so manager.dispose() calls dispose() twice on the same object by design. I reproduced this: without the guard the second call crashes with sodium_memzero: buf must be a typed array. So reverting doesn't just make user double-dispose UB; it makes our own teardown path throw. More generally, idempotent disposal is the standard contract precisely because cleanup graphs overlap: .NET's IDisposable mandates it ("must ignore all calls after the first one") and TC39's DisposableStack.dispose() is specified as a no-op when already disposed. The guard is two lines; I'd rather keep teardown order-independent than make every owner coordinate who disposes first. I also added double-dispose tests to both signer suites in #95 to lock the contract in.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, this makes sense. I have a suggestion for a different improvement. I'll post it here though, since i don't think there is a better place. Since the 'dispose' method now exists in multiple interfaces and abstract classes i.e., 'WalletManager', 'IWalletAccount', 'ISigner', it would be better to create an ad-hoc type for it and make them implement it. Your mention to .NET's IDisposable made me remember this improvement i thought about some weeks ago. Feel free to add these changes to wdk-wallet pr#52. // /src/disposable.js
/** @interface */
export class IDisposable {
/**
* Disposes the object along with all its data (cleaning up any sensitive field from memory).
*/
dispose () {
throw new NotImplementedError('dispose()')
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice idea, done in wdk-wallet#52: added src/disposable.js with IDisposable as you spec'd, ISigner now extends it (its own dispose stub is gone), and IWalletAccount/WalletManager implement it. The concrete signers and accounts needed no changes, they already implement dispose() and inherit the contract through the interface chain. |
||
| sodium_memzero(this._privateKeyBuffer) | ||
| this._privateKeyBuffer = undefined | ||
| } | ||
| } | ||
| } | ||
|
Davi0kProgramsThings marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // Copyright 2024 Tether Operations Limited | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // src/signers/index.js | ||
| /** | ||
| * Barrel exports for EVM signers. | ||
| * | ||
| * - `SeedSignerEvm`: derives accounts from a BIP-39 seed (BIP-44 path). | ||
| * - `PrivateKeySignerEvm`: memory-safe wrapper around a raw private key. | ||
| */ | ||
| export { default, default as SeedSignerEvm } from './seed-signer-evm.js' | ||
| export { default as PrivateKeySignerEvm } from './private-key-signer-evm.js' |
Uh oh!
There was an error while loading. Please reload this page.