mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
94 lines
3.2 KiB
Rust
94 lines
3.2 KiB
Rust
// Copyright 2022 The Grin Developers
|
|
//
|
|
// 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.
|
|
|
|
//! Implementation of contract sign
|
|
|
|
use crate::backend::WalletBackend;
|
|
use crate::contract;
|
|
use crate::contract::actions::setup;
|
|
use crate::contract::types::ContractSetupArgsAPI;
|
|
use crate::error::Error;
|
|
use crate::grin_keychain::Keychain;
|
|
use crate::grin_util::secp::key::SecretKey;
|
|
use crate::slate::Slate;
|
|
use crate::types::{Context, NodeClient};
|
|
|
|
/// Sign a contract
|
|
pub fn sign<C, K>(
|
|
w: &mut WalletBackend<C, K>,
|
|
keychain_mask: Option<&SecretKey>,
|
|
slate: &Slate,
|
|
setup_args: &ContractSetupArgsAPI,
|
|
) -> Result<Slate, Error>
|
|
where
|
|
C: NodeClient,
|
|
K: Keychain,
|
|
{
|
|
// Compute if we will add outputs at this step. Only a missing context means we
|
|
// still need to add them; propagate any other error.
|
|
let will_add_outputs = match w.get_private_context(keychain_mask, slate.id.as_bytes()) {
|
|
Ok(ctx) => ctx.get_inputs().len() + ctx.get_outputs().len() == 0,
|
|
Err(Error::NotFoundErr(_)) => true,
|
|
Err(e) => return Err(e),
|
|
};
|
|
// Compute state for 'sign'
|
|
let (sl, mut context) = compute(w, keychain_mask, slate, setup_args)?;
|
|
|
|
// Atomically commit state
|
|
contract::utils::save_step(w, keychain_mask, &sl, &mut context, will_add_outputs, true)?;
|
|
|
|
Ok(sl)
|
|
}
|
|
|
|
/// Compute logic for sign
|
|
pub fn compute<C, K>(
|
|
w: &mut WalletBackend<C, K>,
|
|
keychain_mask: Option<&SecretKey>,
|
|
slate: &Slate,
|
|
setup_args: &ContractSetupArgsAPI,
|
|
) -> Result<(Slate, Context), Error>
|
|
where
|
|
C: NodeClient,
|
|
K: Keychain,
|
|
{
|
|
let mut sl = slate.clone();
|
|
contract::utils::verify_not_signed(w, sl.id)?;
|
|
|
|
// Ensure net_change has been provided
|
|
let expected_net_change =
|
|
contract::utils::get_net_change(w, keychain_mask, &sl.id, setup_args.net_change)?;
|
|
|
|
// Define the values that must be provided in the setup phase at the sign step
|
|
let mut setup_args = setup_args.clone();
|
|
setup_args.net_change = Some(expected_net_change);
|
|
setup_args.num_participants = sl.num_participants;
|
|
setup_args.add_outputs = true; // we add outputs to the Context in case we haven't done that yet
|
|
|
|
// Ensure Setup phase is done and that inputs/outputs have been added to the Context
|
|
let (mut sl, mut context) = setup::compute(w, keychain_mask, &mut sl, &setup_args)?;
|
|
// Add outputs to the slate, verify the payment proof and sign the slate
|
|
contract::slate::add_outputs(w, keychain_mask, &mut sl, &context)?;
|
|
contract::slate::verify_invoice_promise(&sl, &w.keychain(keychain_mask)?, &context)?;
|
|
|
|
contract::slate::sign(w, keychain_mask, &mut sl, &mut context)?;
|
|
contract::slate::transition_state(&mut sl)?;
|
|
|
|
// If we have all the partial signatures, finalize the tx
|
|
if contract::slate::can_finalize(&sl) {
|
|
contract::slate::finalize(w, keychain_mask, &mut sl)?;
|
|
}
|
|
|
|
Ok((sl, context))
|
|
}
|