mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-01-21 03:21:08 +03:00
Slate compatibility between versions (#35)
* wallet compatibilities * rustfmt
This commit is contained in:
parent
2d8a6b81e0
commit
0e9ccef3e5
4 changed files with 115 additions and 24 deletions
|
@ -763,14 +763,14 @@ where
|
||||||
Box::new(parse_body(req).and_then(
|
Box::new(parse_body(req).and_then(
|
||||||
//TODO: No way to insert a message from the params
|
//TODO: No way to insert a message from the params
|
||||||
move |slate_str: String| {
|
move |slate_str: String| {
|
||||||
let mut slate: Slate = Slate::deserialize_upgrade(&slate_str).unwrap();
|
let slate: Slate = Slate::deserialize_upgrade(&slate_str).unwrap();
|
||||||
if let Err(e) = api.verify_slate_messages(&slate) {
|
if let Err(e) = api.verify_slate_messages(&slate) {
|
||||||
error!("Error validating participant messages: {}", e);
|
error!("Error validating participant messages: {}", e);
|
||||||
err(e)
|
err(e)
|
||||||
} else {
|
} else {
|
||||||
match api.receive_tx(&mut slate, None, None) {
|
match api.receive_tx(&slate, None, None) {
|
||||||
Ok(_) => ok(slate
|
Ok(s) => ok(s
|
||||||
.serialize_to_version(Some(slate.version_info.orig_version))
|
.serialize_to_version(Some(s.version_info.orig_version))
|
||||||
.unwrap()),
|
.unwrap()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("receive_tx: failed with error: {}", e);
|
error!("receive_tx: failed with error: {}", e);
|
||||||
|
@ -798,7 +798,7 @@ where
|
||||||
),
|
),
|
||||||
"receive_tx" => Box::new(
|
"receive_tx" => Box::new(
|
||||||
self.receive_tx(req, api)
|
self.receive_tx(req, api)
|
||||||
.and_then(|res| ok(json_response(&res))),
|
.and_then(|res| ok(json_response_slate(&res))),
|
||||||
),
|
),
|
||||||
_ => Box::new(ok(response(StatusCode::BAD_REQUEST, "unknown action"))),
|
_ => Box::new(ok(response(StatusCode::BAD_REQUEST, "unknown action"))),
|
||||||
}
|
}
|
||||||
|
@ -909,6 +909,29 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As above, dealing with stringified slate output
|
||||||
|
// from older versions.
|
||||||
|
// Older versions are expecting a slate objects, anything from
|
||||||
|
// 1.1.0 up is expecting a string
|
||||||
|
fn json_response_slate<T>(s: &T) -> Response<Body>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
match serde_json::to_string(s) {
|
||||||
|
Ok(mut json) => {
|
||||||
|
if let None = json.find("version_info") {
|
||||||
|
let mut r = json.clone();
|
||||||
|
r.pop();
|
||||||
|
r.remove(0);
|
||||||
|
// again, for backwards slate compat
|
||||||
|
json = r.replace("\\\"", "\"")
|
||||||
|
}
|
||||||
|
response(StatusCode::OK, json)
|
||||||
|
}
|
||||||
|
Err(_) => response(StatusCode::INTERNAL_SERVER_ERROR, ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pretty-printed version of above
|
// pretty-printed version of above
|
||||||
fn json_response_pretty<T>(s: &T) -> Response<Body>
|
fn json_response_pretty<T>(s: &T) -> Response<Body>
|
||||||
where
|
where
|
||||||
|
@ -987,10 +1010,26 @@ where
|
||||||
req.into_body()
|
req.into_body()
|
||||||
.concat2()
|
.concat2()
|
||||||
.map_err(|_| ErrorKind::GenericError("Failed to read request".to_owned()).into())
|
.map_err(|_| ErrorKind::GenericError("Failed to read request".to_owned()).into())
|
||||||
.and_then(|body| match serde_json::from_reader(&body.to_vec()[..]) {
|
.and_then(|body| {
|
||||||
|
match serde_json::from_reader(&body.to_vec()[..]) {
|
||||||
Ok(obj) => ok(obj),
|
Ok(obj) => ok(obj),
|
||||||
Err(e) => {
|
Err(_) => {
|
||||||
err(ErrorKind::GenericError(format!("Invalid request body: {}", e)).into())
|
// try to parse as string instead, for backwards compatibility
|
||||||
|
let replaced_str = String::from_utf8(body.to_vec().clone())
|
||||||
|
.unwrap()
|
||||||
|
.replace("\"", "\\\"");
|
||||||
|
let mut str_vec = replaced_str.as_bytes().to_vec();
|
||||||
|
str_vec.push(0x22);
|
||||||
|
str_vec.insert(0, 0x22);
|
||||||
|
match serde_json::from_reader(&str_vec[..]) {
|
||||||
|
Ok(obj) => ok(obj),
|
||||||
|
Err(e) => err(ErrorKind::GenericError(format!(
|
||||||
|
"Invalid request body: {}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
/// HTTP Wallet 'plugin' implementation
|
/// HTTP Wallet 'plugin' implementation
|
||||||
use crate::api;
|
use crate::api;
|
||||||
use crate::libwallet::slate::Slate;
|
use crate::libwallet::slate::Slate;
|
||||||
|
use crate::libwallet::slate_versions::{v0, v1};
|
||||||
use crate::libwallet::{Error, ErrorKind};
|
use crate::libwallet::{Error, ErrorKind};
|
||||||
use crate::WalletCommAdapter;
|
use crate::WalletCommAdapter;
|
||||||
use config::WalletConfig;
|
use config::WalletConfig;
|
||||||
|
use failure::ResultExt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -47,16 +49,65 @@ impl WalletCommAdapter for HTTPWalletCommAdapter {
|
||||||
let url = format!("{}/v1/wallet/foreign/receive_tx", dest);
|
let url = format!("{}/v1/wallet/foreign/receive_tx", dest);
|
||||||
debug!("Posting transaction slate to {}", url);
|
debug!("Posting transaction slate to {}", url);
|
||||||
let slate = slate.serialize_to_version(Some(slate.version_info.orig_version))?;
|
let slate = slate.serialize_to_version(Some(slate.version_info.orig_version))?;
|
||||||
|
// For compatibility with older clients
|
||||||
|
let res: Slate = {
|
||||||
|
if let None = slate.find("version_info") {
|
||||||
|
let version = Slate::parse_slate_version(&slate)?;
|
||||||
|
match version {
|
||||||
|
1 => {
|
||||||
|
let ver1: v1::SlateV1 =
|
||||||
|
serde_json::from_str(&slate).context(ErrorKind::SlateDeser)?;
|
||||||
|
let r: Result<v1::SlateV1, _> =
|
||||||
|
api::client::post(url.as_str(), None, &ver1);
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
let report = format!(
|
||||||
|
"Posting transaction slate (is recipient listening?): {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
error!("{}", report);
|
||||||
|
return Err(ErrorKind::ClientCallback(report).into());
|
||||||
|
}
|
||||||
|
Ok(s) => Slate::deserialize_upgrade(
|
||||||
|
&serde_json::to_string(&s).context(ErrorKind::SlateDeser)?,
|
||||||
|
)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let ver0: v0::SlateV0 =
|
||||||
|
serde_json::from_str(&slate).context(ErrorKind::SlateDeser)?;
|
||||||
|
let r: Result<v0::SlateV0, _> =
|
||||||
|
api::client::post(url.as_str(), None, &ver0);
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
let report = format!(
|
||||||
|
"Posting transaction slate (is recipient listening?): {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
error!("{}", report);
|
||||||
|
return Err(ErrorKind::ClientCallback(report).into());
|
||||||
|
}
|
||||||
|
Ok(s) => Slate::deserialize_upgrade(
|
||||||
|
&serde_json::to_string(&s).context(ErrorKind::SlateDeser)?,
|
||||||
|
)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let res: Result<String, _> = api::client::post(url.as_str(), None, &slate);
|
let res: Result<String, _> = api::client::post(url.as_str(), None, &slate);
|
||||||
match res {
|
match res {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let report = format!("Posting transaction slate (is recipient listening?): {}", e);
|
let report =
|
||||||
|
format!("Posting transaction slate (is recipient listening?): {}", e);
|
||||||
error!("{}", report);
|
error!("{}", report);
|
||||||
Err(ErrorKind::ClientCallback(report).into())
|
return Err(ErrorKind::ClientCallback(report).into());
|
||||||
}
|
}
|
||||||
Ok(r) => Ok(Slate::deserialize_upgrade(&r)?),
|
Ok(r) => Slate::deserialize_upgrade(&r)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
fn send_tx_async(&self, _dest: &str, _slate: &Slate) -> Result<(), Error> {
|
fn send_tx_async(&self, _dest: &str, _slate: &Slate) -> Result<(), Error> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
|
|
@ -163,9 +163,9 @@ pub struct ParticipantMessages {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slate {
|
impl Slate {
|
||||||
// TODO: Reduce the number of changes that need to occur below for each new
|
/// TODO: Reduce the number of changes that need to occur below for each new
|
||||||
// slate version
|
/// slate version
|
||||||
fn parse_slate_version(slate_json: &str) -> Result<u16, Error> {
|
pub fn parse_slate_version(slate_json: &str) -> Result<u16, Error> {
|
||||||
// keep attempting to deser, working through known versions until we have
|
// keep attempting to deser, working through known versions until we have
|
||||||
// enough to get the version out
|
// enough to get the version out
|
||||||
let res: Result<SlateV2, serde_json::Error> = serde_json::from_str(slate_json);
|
let res: Result<SlateV2, serde_json::Error> = serde_json::from_str(slate_json);
|
||||||
|
@ -218,7 +218,8 @@ impl Slate {
|
||||||
1 => {
|
1 => {
|
||||||
let v2: SlateV2 = serde_json::from_str(&ser_self).context(ErrorKind::SlateDeser)?;
|
let v2: SlateV2 = serde_json::from_str(&ser_self).context(ErrorKind::SlateDeser)?;
|
||||||
let v1 = SlateV1::from(v2);
|
let v1 = SlateV1::from(v2);
|
||||||
Ok(serde_json::to_string(&v1).context(ErrorKind::SlateDeser)?)
|
let slate = serde_json::to_string(&v1).context(ErrorKind::SlateDeser)?;
|
||||||
|
Ok(slate)
|
||||||
}
|
}
|
||||||
0 => {
|
0 => {
|
||||||
let v2: SlateV2 = serde_json::from_str(&ser_self).context(ErrorKind::SlateDeser)?;
|
let v2: SlateV2 = serde_json::from_str(&ser_self).context(ErrorKind::SlateDeser)?;
|
||||||
|
|
|
@ -397,10 +397,10 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
||||||
|
|
||||||
// target slate version to create/send
|
// target slate version to create/send
|
||||||
let target_slate_version = {
|
let target_slate_version = {
|
||||||
match args.is_present("target_slate_version") {
|
match args.is_present("slate_version") {
|
||||||
true => {
|
true => {
|
||||||
let v = parse_required(args, "target_slate_version")?;
|
let v = parse_required(args, "slate_version")?;
|
||||||
Some(parse_u64(v, "target_slate_version")? as u16)
|
Some(parse_u64(v, "slate_version")? as u16)
|
||||||
}
|
}
|
||||||
false => None,
|
false => None,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue