Conversation
ikripaka
commented
Jan 21, 2026
- Signer trait would help in future create easy to use finalization of transactions
simplicity-coresimplicity-contracts
e74b649 to
c8ba908
Compare
simplicity-contractssimplicity-core
|
|
||
| /// Get the dummy keypair used for fee estimation. | ||
| /// This keypair is deterministic and used only to produce valid transaction structures. | ||
| #[allow(unused)] |
There was a problem hiding this comment.
clippy warns about it
DummySigner can be used in some tests
There was a problem hiding this comment.
Why we are adding private functionality to the crate which intention to provide tools for external crates?
There was a problem hiding this comment.
ok, in some case DummySigner can be deleted , because can be unused by others
| /// Returns a closure that signs a transaction with dummy signatures. | ||
| /// | ||
| /// This is used for fee estimation - the transaction needs valid witness data | ||
| /// to calculate accurate weight/fees, but the actual signatures don't need | ||
| /// to be cryptographically valid for spending (they just need to be the right size). | ||
| #[allow(clippy::type_complexity, unused)] | ||
| pub(crate) fn get_signer_closure() -> impl SignerTrait { | ||
| |network: SimplicityNetwork, tx: Transaction, utxos: &[TxOut]| { | ||
| let keypair = Self::get_dummy_keypair(); | ||
| let x_only_public_key = keypair.x_only_public_key().0; | ||
| let p2pk_program = get_p2pk_program(&x_only_public_key)?; | ||
| let cmr = p2pk_program.commit().cmr(); | ||
|
|
||
| let dummy_address = | ||
| create_p2tr_address(cmr, &x_only_public_key, network.address_params()); | ||
| let dummy_script_pubkey = dummy_address.script_pubkey(); | ||
|
|
||
| let dummy_utxos: Vec<TxOut> = utxos | ||
| .iter() | ||
| .map(|utxo: &TxOut| TxOut { | ||
| script_pubkey: dummy_script_pubkey.clone(), | ||
| ..utxo.clone() | ||
| }) | ||
| .collect(); | ||
|
|
||
| let mut signed_tx = tx; | ||
|
|
||
| for i in 0..signed_tx.input.len() { | ||
| let signature = | ||
| create_p2pk_signature(&signed_tx, &dummy_utxos, &keypair, i, network)?; | ||
|
|
||
| signed_tx = finalize_p2pk_transaction( | ||
| signed_tx, | ||
| &dummy_utxos, | ||
| &x_only_public_key, | ||
| &signature, | ||
| i, | ||
| network, | ||
| TrackerLogLevel::None, | ||
| )?; | ||
| } | ||
|
|
||
| Ok(signed_tx) | ||
| } | ||
| } |
There was a problem hiding this comment.
The function name and what it actually does is different
There was a problem hiding this comment.
That is the DummySigner - the idea was to create type, which would be responsible for signing, which doesn't require valid Keypair for signing.
Due to internal checks of ScriptPubkey we have to manually change owner of utxo.
Yeah, it changes owner of utxo on draft keypair and signs as p2pk utxo.
| pub trait SignerTrait: | ||
| Fn(SimplicityNetwork, Transaction, &[TxOut]) -> Result<Transaction, ProgramError> + Clone | ||
| { | ||
| } | ||
|
|
||
| impl<T> SignerTrait for T where | ||
| T: Fn(SimplicityNetwork, Transaction, &[TxOut]) -> Result<Transaction, ProgramError> + Clone | ||
| { | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| pub trait SignerOnceTrait: | ||
| FnOnce(SimplicityNetwork, Transaction, &[TxOut]) -> Result<Transaction, ProgramError> | ||
| { | ||
| } | ||
|
|
||
| impl<T> SignerOnceTrait for T where | ||
| T: FnOnce(SimplicityNetwork, Transaction, &[TxOut]) -> Result<Transaction, ProgramError> | ||
| { | ||
| } |
There was a problem hiding this comment.
For standard finalization, if we need to calculate fees from scratch we must call valid signing function twice.
However if we provide our own values the transaction would be signed only once.
Therefore this traits can be used to bound the invocation of sign functions.
We can use SignerTrait to invoke another function that is bounded by SignerOnceTrait.
- since
SignerTraitis anFn, it implementsFnOnceby default. This allows us to invoke a function that performs the signing operation only once. SignerOnceTraitcan also be used in external code by users who want to restrict specific traits to sign function that can only be called once.
There was a problem hiding this comment.
So the the idea lies in restricting even inner functions to FnOnce even if we receive Fn
| let dummy_utxos: Vec<TxOut> = utxos | ||
| .iter() | ||
| .map(|utxo: &TxOut| TxOut { | ||
| script_pubkey: dummy_script_pubkey.clone(), |
There was a problem hiding this comment.
ok, exactly in this case I wanted to define DummySigner as draft one, which can be used in any case
by using it wihout script_pubkey is impossible, code would fail
we can redefine it with trait which would give Keypair type to function and sign only with p2pk(lets say P2pkSigner), but in this way we mabe lose flexibilty of creating signature to any utxo
I mean some utxos has to be signed in another way than p2pk
(I've looked through all signing functions and by now we only require p2pk)
So, maybe it makes sense to define DummySigner as P2pkSigner, which would by giving
There was a problem hiding this comment.
ok, maybe it makes sense to define signer like this?
pub trait P2PKSigner {
fn x_only_public_key() -> XOnlyPublicKey;
fn sign_p2pk_utxo(&self, network: SimplicityNetwork, tx: Transaction, utxos: &[TxOut], input_index: usize) -> Result<Transaction, ProgramError>;
}
pub struct SimpleSigner {}
impl P2PKSigner for SimpleSigner {
fn sign_p2pk_utxo(&self, network: SimplicityNetwork, tx: Transaction, utxos: &[TxOut], input_index: usize) -> Result<Transaction, ProgramError>{
keypair.sign_schnorr(sighash_all)
}
}There was a problem hiding this comment.
we would leave Keypair storage on the Wallet or any user implementation and in the same way we'd feed signed bytes into our backend where it is needed
| @@ -0,0 +1,92 @@ | |||
| use crate::{ | |||
There was a problem hiding this comment.
It is unclear how it should be used
There was a problem hiding this comment.
It should be used together with simplicityhl-core errors and functions
functions is related only to DummySigner, but trait can be used with ProgramError
|
I would like to reiterate on the approach, closing the PR for the time being |