mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 15:21:39 +02:00
[CONTRACTS] Contracts branch update for 1.80 (#718)
* Simple contracts restructured v3 (#675) * Add prototype contract implementation Lacks: - Payment proofs (add early payment proofs) - Tests - Better structure * Separate contract utilities * Simplify the main setup/sign code flow * Remove commented initial_sec_key assignment * Simplify sign::compute function * Add logic for "removal" of secret keys from the context * Further simplify a bit sign and setup * No need for mutable context when adding outputs * Refactor the commented code (lol) * Refactor a bit * tmp --------- Co-authored-by: oryhp <gtrphyro@gmail.com> * contract test fixes (#676) * [Contracts] Experimental Slate v5 (#677) * beginning to add and modify slate version 5 * completion of conversions from V5 to V4 Slate * timestamp and memo fields * upgrade/downgrade serialization of v5 slates * add v5 binary slate versions + start of tests * add bin slate ser/deser to tests * ensure serialization of timestamp always excludes milliseconds * start to update v5 tests, update v5 documentation * add fn to generate populated internal slate for conversion testing * add basic tests to convert all slate versions * update * commit cargo.lock * [WIP] [Contracts] Early payment proofs (#681) * add types and beginnings of signature utils * add proof serialization * serialisation of proof data + signature operation * add serialization type for invoice proof + separate bin wrapper version * add witness data + serializion to invoice payment proof, insert verfication functions in place in order to begin verification testing * tests and infrastructure in place for validation * verification of promise sig * added verification of promise signature, infrastructure up to the point where a signature must be subtracted * attempting to figure out differences between recipient nonce that's getting stored and calculated recipient nonce * implementation of witness verification function, retrieve relevant values and re-validate derived recipient partial signature * move stored portion of invoice proof into core types for storage, need to rename invoice proof * define/refine the stored portion of payment proofs type 2? * Folding all proof data into tx log entry storage * back to importing master * remove cargo files from diffs * remove a lot of extra debug output * return proof witness as part of proof retrieval, define json serialization of invoice proof + witness fields * finish adding verification steps to foreign API * remove redundant promise sig field * move lcation of sign/verify calls * Replace Azure Pipelines with Github Actions (#688) * Update CI Badge on README.MD (#690) * Trigger CI on push and pull request (#693) * Update versioning to 5.2.0-beta.1 against grin 5.2.0-beta.3 (#691) * update versioning to 5.2.0-beta.1 against grin 5.2.0-beta.3 * tweak for CI trigger --------- Co-authored-by: Quentin Le Sceller <q.lesceller@gmail.com> --------- Co-authored-by: Quentin Le Sceller <q.lesceller@gmail.com> * fix Cargo.lock * Contracts - Test fixes + warning cleanups (#694) * clean up warnings in libwallet crate * clean up warnings in controller crate * update all contract tests with awareness of new proof structure * added explicit payment proof tests for both rsr and srs (#695) * Basic mwmixnet send (#696) * integrating onion library * updates and changes to support newly included mwmixnet types * add (incorrect) owner api function * turn off test for now * switch working grin branch to master * fix doctests for build * update cargo lock in attempt to fix croaring build on CI server * update cargo lock with upstream thiserror crate * update test dependency for croaring * [Contracts] Add self spend transaction state (#697) * Add self spend transaction state * subtle errors with output states and tx lookups - fixes * [Contracts] Slatepack v5 Deserialization fix (#698) * add V5 deserialization test + fixes * clarify comment * upwrap fix during v4 deserialization * further unwrap removal * update cargo lock, use latest grin packages * addition of self-spend cancel + tests (#699) * add tests + legacy self send cancel (#702) * [Contracts] Cancel self-spend TX Pt. 2 (#703) * add tests + legacy self send cancel * add missing file * Update grin to latest master, change versioning label to include contracts (#712) * Add owner_api_listen_interface as hidden configuration field (#714) * updates for rust 1.80 * updates for rust 1.80 --------- Co-authored-by: oryhp <gtrphyro@gmail.com> Co-authored-by: Quentin Le Sceller <q.lesceller@gmail.com>
This commit is contained in:
co-authored by
oryhp
Quentin Le Sceller
parent
765f11b168
commit
cdd63fb565
+8
-8
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "grin_wallet_api"
|
||||
version = "5.4.0-alpha.1"
|
||||
version = "5.4.0-contracts.0"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
description = "Grin Wallet API"
|
||||
license = "Apache-2.0"
|
||||
@@ -22,17 +22,17 @@ ring = "0.16"
|
||||
base64 = "0.12"
|
||||
ed25519-dalek = "1.0.0-pre.4"
|
||||
|
||||
grin_wallet_libwallet = { path = "../libwallet", version = "5.4.0-alpha.1" }
|
||||
grin_wallet_config = { path = "../config", version = "5.4.0-alpha.1" }
|
||||
grin_wallet_impls = { path = "../impls", version = "5.4.0-alpha.1" }
|
||||
grin_wallet_util = { path = "../util", version = "5.4.0-alpha.1" }
|
||||
grin_wallet_libwallet = { path = "../libwallet", version = "5.4.0-contracts.0" }
|
||||
grin_wallet_config = { path = "../config", version = "5.4.0-contracts.0" }
|
||||
grin_wallet_impls = { path = "../impls", version = "5.4.0-contracts.0" }
|
||||
grin_wallet_util = { path = "../util", version = "5.4.0-contracts.0" }
|
||||
|
||||
##### Grin Imports
|
||||
|
||||
# For Release
|
||||
# grin_core = "5.4.0-alpha.1"
|
||||
# grin_keychain = "5.4.0-alpha.1"
|
||||
# grin_util = "5.4.0-alpha.1"
|
||||
# grin_core = "5.4.0-contracts.0"
|
||||
# grin_keychain = "5.4.0-contracts.0"
|
||||
# grin_util = "5.4.0-contracts.0"
|
||||
|
||||
# For beta release
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
use crate::config::TorConfig;
|
||||
use crate::keychain::Keychain;
|
||||
use crate::libwallet::api_impl::foreign;
|
||||
use crate::libwallet::contract::proofs::InvoiceProof;
|
||||
use crate::libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
|
||||
use crate::libwallet::{
|
||||
BlockFees, CbData, Error, NodeClient, NodeVersionInfo, Slate, VersionInfo, WalletInst,
|
||||
WalletLCProvider,
|
||||
@@ -24,6 +26,7 @@ use crate::libwallet::{
|
||||
use crate::try_slatepack_sync_workflow;
|
||||
use crate::util::secp::key::SecretKey;
|
||||
use crate::util::Mutex;
|
||||
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// ForeignAPI Middleware Check callback
|
||||
@@ -450,6 +453,43 @@ where
|
||||
post_automatically,
|
||||
)
|
||||
}
|
||||
|
||||
// Below is a foreign wrapper around owner calls to 'new' and 'sign' which are only executed
|
||||
// if this is a receiving contract. This preserves the ability to receive on a foreign interface.
|
||||
/// TODO
|
||||
pub fn contract_new(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
args: &ContractNewArgsAPI,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
// TODO: self.doctest_mode ?
|
||||
foreign::contract_new(&mut **w, keychain_mask, &args)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn contract_sign(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
slate: &Slate,
|
||||
args: &ContractSetupArgsAPI,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
foreign::contract_sign(&mut **w, keychain_mask, &args, &slate)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn verify_payment_proof_invoice(
|
||||
&self,
|
||||
recipient_address: &DalekPublicKey,
|
||||
proof: &InvoiceProof,
|
||||
) -> Result<(), Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
foreign::verify_payment_proof_invoice(&mut **w, recipient_address, proof)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
||||
@@ -52,6 +52,7 @@ pub trait ForeignRpc {
|
||||
"Ok": {
|
||||
"foreign_api_version": 2,
|
||||
"supported_slate_versions": [
|
||||
"V5",
|
||||
"V4"
|
||||
]
|
||||
}
|
||||
@@ -141,7 +142,7 @@ pub trait ForeignRpc {
|
||||
}
|
||||
],
|
||||
"sta": "S1",
|
||||
"ver": "4:2"
|
||||
"ver": "5:2"
|
||||
},
|
||||
null,
|
||||
null
|
||||
@@ -176,7 +177,7 @@ pub trait ForeignRpc {
|
||||
}
|
||||
],
|
||||
"sta": "S2",
|
||||
"ver": "4:2"
|
||||
"ver": "5:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,7 +206,7 @@ pub trait ForeignRpc {
|
||||
"method": "finalize_tx",
|
||||
"id": 1,
|
||||
"params": [{
|
||||
"ver": "4:2",
|
||||
"ver": "5:2",
|
||||
"id": "0436430c-2b02-624c-2032-570501212b00",
|
||||
"sta": "I2",
|
||||
"off": "383bc9df0dd332629520a0a72f8dd7f0e97d579dccb4dbdc8592aa3d424c846c",
|
||||
@@ -275,7 +276,7 @@ pub trait ForeignRpc {
|
||||
}
|
||||
],
|
||||
"sta": "I3",
|
||||
"ver": "4:2"
|
||||
"ver": "5:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
use chrono::prelude::*;
|
||||
use ed25519_dalek::SecretKey as DalekSecretKey;
|
||||
use grin_wallet_libwallet::contract::proofs::InvoiceProof;
|
||||
use grin_wallet_libwallet::RetrieveTxQueryArgs;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -27,6 +28,10 @@ use crate::impls::SlateSender as _;
|
||||
use crate::keychain::{Identifier, Keychain};
|
||||
use crate::libwallet::api_impl::owner_updater::{start_updater_log_thread, StatusMessage};
|
||||
use crate::libwallet::api_impl::{owner, owner_updater};
|
||||
use crate::libwallet::contract::types::{
|
||||
ContractNewArgsAPI, ContractRevokeArgsAPI, ContractSetupArgsAPI,
|
||||
};
|
||||
use crate::libwallet::mwmixnet::types::{MixnetReqCreationParams, SwapReq};
|
||||
use crate::libwallet::{
|
||||
AcctPathMapping, BuiltOutput, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
|
||||
NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, Slatepack, SlatepackAddress,
|
||||
@@ -766,6 +771,78 @@ where
|
||||
owner::issue_invoice_tx(&mut **w, keychain_mask, args, self.doctest_mode)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn contract_new(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
args: &ContractNewArgsAPI,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
// TODO: self.doctest_mode ?
|
||||
owner::contract_new(&mut **w, keychain_mask, &args)
|
||||
}
|
||||
|
||||
// /// TODO
|
||||
// pub fn contract_setup(
|
||||
// &self,
|
||||
// keychain_mask: Option<&SecretKey>,
|
||||
// slate: &Slate,
|
||||
// args: &ContractSetupArgsAPI,
|
||||
// ) -> Result<Slate, Error> {
|
||||
// let mut w_lock = self.wallet_inst.lock();
|
||||
// let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
// // TODO: self.doctest_mode ?
|
||||
// owner::contract_setup(&mut **w, keychain_mask, &args, &slate)
|
||||
// }
|
||||
|
||||
/// TODO
|
||||
pub fn contract_sign(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
slate: &Slate,
|
||||
args: &ContractSetupArgsAPI,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::contract_sign(&mut **w, keychain_mask, &args, &slate)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn get_slate_index_matching_my_context(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
slate: &Slate,
|
||||
) -> Result<usize, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::get_slate_index_matching_my_context(&mut **w, keychain_mask, &slate)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn contract_revoke(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
args: &ContractRevokeArgsAPI,
|
||||
) -> Result<Option<Slate>, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::contract_revoke(&mut **w, keychain_mask, &args)
|
||||
}
|
||||
|
||||
/// Create MXMixnet request
|
||||
pub fn create_mwmixnet_req(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
params: &MixnetReqCreationParams,
|
||||
slate: &Slate,
|
||||
// use_test_rng: bool,
|
||||
) -> Result<SwapReq, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::create_mwmixnet_req(&mut **w, keychain_mask, params, slate)
|
||||
}
|
||||
|
||||
/// Processes an invoice tranaction created by another party, essentially
|
||||
/// a `request for payment`. The incoming slate should contain a requested
|
||||
/// amount, an output created by the invoicer convering the amount, and
|
||||
@@ -2355,6 +2432,32 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
/// TODO: Temporary, likely should merge with above
|
||||
pub fn retrieve_payment_proof_invoice(
|
||||
&self,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
refresh_from_node: bool,
|
||||
tx_id: Option<u32>,
|
||||
tx_slate_id: Option<Uuid>,
|
||||
) -> Result<InvoiceProof, Error> {
|
||||
let tx = {
|
||||
let t = self.status_tx.lock();
|
||||
t.clone()
|
||||
};
|
||||
let refresh_from_node = match self.updater_running.load(Ordering::Relaxed) {
|
||||
true => false,
|
||||
false => refresh_from_node,
|
||||
};
|
||||
owner::retrieve_payment_proof_invoice(
|
||||
self.wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
&tx,
|
||||
refresh_from_node,
|
||||
tx_id,
|
||||
tx_slate_id,
|
||||
)
|
||||
}
|
||||
|
||||
/// Verifies a [PaymentProof](../grin_wallet_libwallet/api_impl/types/struct.PaymentProof.html)
|
||||
/// This process entails:
|
||||
///
|
||||
|
||||
+106
-3
@@ -20,6 +20,9 @@ use crate::config::{TorConfig, WalletConfig};
|
||||
use crate::core::core::OutputFeatures;
|
||||
use crate::core::global;
|
||||
use crate::keychain::{Identifier, Keychain};
|
||||
use crate::libwallet::contract::types::{
|
||||
ContractNewArgsAPI, ContractRevokeArgsAPI, ContractSetupArgsAPI,
|
||||
};
|
||||
use crate::libwallet::{
|
||||
AcctPathMapping, Amount, BuiltOutput, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
|
||||
NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, SlateVersion, Slatepack,
|
||||
@@ -501,7 +504,7 @@ pub trait OwnerRpc {
|
||||
}
|
||||
],
|
||||
"sta": "S1",
|
||||
"ver": "4:2"
|
||||
"ver": "5:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,8 +513,49 @@ pub trait OwnerRpc {
|
||||
```
|
||||
*/
|
||||
|
||||
/**
|
||||
TODO: Full docs once API has stabilised
|
||||
*/
|
||||
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, Error>;
|
||||
|
||||
/**
|
||||
TODO: Implement
|
||||
*/
|
||||
// fn contract_setup(
|
||||
// &self,
|
||||
// token: Token,
|
||||
// slate: VersionedSlate,
|
||||
// args: ContractSetupArgsAPI,
|
||||
// ) -> Result<VersionedSlate, Error>;
|
||||
|
||||
/**
|
||||
TODO: Full docs once API has stabilised
|
||||
*/
|
||||
|
||||
fn contract_new(&self, token: Token, args: ContractNewArgsAPI)
|
||||
-> Result<VersionedSlate, Error>;
|
||||
|
||||
/**
|
||||
TODO: Full docs once API has stabilised
|
||||
*/
|
||||
|
||||
fn contract_sign(
|
||||
&self,
|
||||
token: Token,
|
||||
slate: VersionedSlate,
|
||||
args: ContractSetupArgsAPI,
|
||||
) -> Result<VersionedSlate, Error>;
|
||||
|
||||
/**
|
||||
TODO: Full docs once API has stabilised
|
||||
*/
|
||||
|
||||
fn contract_revoke(
|
||||
&self,
|
||||
token: Token,
|
||||
args: ContractRevokeArgsAPI,
|
||||
) -> Result<Option<VersionedSlate>, Error>;
|
||||
|
||||
/**
|
||||
;Networked version of [Owner::issue_invoice_tx](struct.Owner.html#method.issue_invoice_tx).
|
||||
|
||||
@@ -548,7 +592,7 @@ pub trait OwnerRpc {
|
||||
}
|
||||
],
|
||||
"sta": "I1",
|
||||
"ver": "4:2"
|
||||
"ver": "5:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -919,7 +963,7 @@ pub trait OwnerRpc {
|
||||
"id": "0436430c-2b02-624c-2032-570501212b00",
|
||||
"sigs": [],
|
||||
"sta": "S3",
|
||||
"ver": "4:3"
|
||||
"ver": "5:3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2052,6 +2096,65 @@ where
|
||||
VersionedSlate::into_version(slate, version)
|
||||
}
|
||||
|
||||
fn contract_new(
|
||||
&self,
|
||||
token: Token,
|
||||
args: ContractNewArgsAPI,
|
||||
) -> Result<VersionedSlate, Error> {
|
||||
let slate = Owner::contract_new(self, (&token.keychain_mask).as_ref(), &args)?;
|
||||
let version = SlateVersion::V4;
|
||||
VersionedSlate::into_version(slate, version)
|
||||
}
|
||||
|
||||
// fn contract_setup(
|
||||
// &self,
|
||||
// token: Token,
|
||||
// in_slate: VersionedSlate,
|
||||
// args: ContractSetupArgsAPI,
|
||||
// ) -> Result<VersionedSlate, Error> {
|
||||
// let slate = Owner::contract_setup(
|
||||
// self,
|
||||
// (&token.keychain_mask).as_ref(),
|
||||
// &Slate::from(in_slate),
|
||||
// &args,
|
||||
// )?;
|
||||
// let version = SlateVersion::V4;
|
||||
// VersionedSlate::into_version(slate, version)
|
||||
// }
|
||||
|
||||
fn contract_sign(
|
||||
&self,
|
||||
token: Token,
|
||||
in_slate: VersionedSlate,
|
||||
args: ContractSetupArgsAPI,
|
||||
) -> Result<VersionedSlate, Error> {
|
||||
let slate = Owner::contract_sign(
|
||||
self,
|
||||
(&token.keychain_mask).as_ref(),
|
||||
&Slate::from(in_slate),
|
||||
&args,
|
||||
)?;
|
||||
let version = SlateVersion::V4;
|
||||
VersionedSlate::into_version(slate, version)
|
||||
}
|
||||
|
||||
fn contract_revoke(
|
||||
&self,
|
||||
token: Token,
|
||||
args: ContractRevokeArgsAPI,
|
||||
) -> Result<Option<VersionedSlate>, Error> {
|
||||
let slate_opt = Owner::contract_revoke(self, (&token.keychain_mask).as_ref(), &args)?;
|
||||
let version = SlateVersion::V4;
|
||||
// We return a slate only when we had to perform a self-spend safe cancel
|
||||
if slate_opt.is_some() {
|
||||
return Ok(Some(VersionedSlate::into_version(
|
||||
slate_opt.unwrap(),
|
||||
version,
|
||||
)?));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn issue_invoice_tx(
|
||||
&self,
|
||||
token: Token,
|
||||
|
||||
Reference in New Issue
Block a user