Skip to content

Commit 6b91983

Browse files
authored
Update VoteCast building procedure (#169)
Distiguish signing of the transaction from building process. So currently it is possible firslty to build a non-signed voteCast transaction via `build_tx` and later sign it with the `sign_tx`.
2 parents 783e096 + e404213 commit 6b91983

File tree

9 files changed

+132
-43
lines changed

9 files changed

+132
-43
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/chain-wallet-libs/bindings/wallet-core/src/tx_builder.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,47 @@ use chain_impl_mockchain::{
55
header::BlockDate,
66
transaction::{Input, Payload, Transaction},
77
};
8-
use wallet::{EitherAccount, Settings};
8+
use std::{collections::HashMap, str::FromStr};
9+
use wallet::{AccountId, EitherAccount, Settings};
910

1011
use crate::Error;
1112

1213
pub struct TxBuilder<P: Payload> {
1314
builder: wallet::TransactionBuilder<P>,
15+
inputs: HashMap<AccountId, (Input, SpendingCounter)>,
1416
}
1517

1618
impl<P: Payload> TxBuilder<P> {
1719
pub fn new(settings: Settings, valid_until: BlockDate, payload: P) -> Self {
1820
let builder = wallet::TransactionBuilder::new(settings, payload, valid_until);
19-
Self { builder }
21+
Self {
22+
builder,
23+
inputs: HashMap::new(),
24+
}
2025
}
2126

2227
pub fn build_tx(
2328
mut self,
24-
account_bytes: &[u8],
29+
account_id_hex: String,
2530
spending_counter: SpendingCounter,
2631
) -> Result<Self, Error> {
32+
let account_id = AccountId::from_str(&account_id_hex)
33+
.map_err(|e| Error::wallet_transaction().with(e))?;
34+
35+
// It is needed to provide a 1 extra input as we are generating it later, but should take into account at this place.
36+
let value = self.builder.estimate_fee_with(1, 0);
37+
let input = Input::from_account_public_key(account_id.into(), value);
38+
self.inputs.insert(account_id, (input, spending_counter));
39+
Ok(self)
40+
}
41+
42+
pub fn sign_tx(mut self, account_bytes: &[u8]) -> Result<Self, Error> {
2743
let account = EitherAccount::new_from_key(
2844
SecretKey::from_binary(account_bytes)
2945
.map_err(|e| Error::wallet_transaction().with(e))?,
3046
);
31-
// It is needed to provide a 1 extra input as we are generating it later, but should take into account at this place.
32-
let value = self.builder.estimate_fee_with(1, 0);
33-
let input = Input::from_account_public_key(account.account_id().into(), value);
47+
48+
let (input, spending_counter) = self.inputs.get(&account.account_id()).ok_or_else(|| Error::invalid_input("Cannot find corresponded input to the provided account, make sure that you have correctly execute build_tx function first"))?.clone();
3449
let witness_builder = account.witness_builder(spending_counter);
3550
self.builder.add_input(input, witness_builder);
3651
Ok(self)

src/chain-wallet-libs/bindings/wallet-wasm-js/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ js-sys = "0.3.40"
3232
bech32 = "0.7.2"
3333
serde_json = "1.0"
3434
hex = "0.4.2"
35+
web-sys = { version = "0.3", features = ["console"] }
3536

3637
# The `console_error_panic_hook` crate provides better debugging of panics by
3738
# logging them with `console.error`. This is great for development, but requires

src/chain-wallet-libs/bindings/wallet-wasm-js/js-test/test/vote_cast.js

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ var assert = require("assert");
33
const private_key =
44
"c86596c2d1208885db1fe3658406aa0f7cc7b8e13c362fe46a6db277fc5064583e487588c98a6c36e2e7445c0add36f83f171cb5ccfd815509d19cd38ecb0af3";
55

6+
const account_id =
7+
"a6a3c0447aeb9cc54cf6422ba32b294e5e1c3ef6d782f2acff4a70694c4d1663";
8+
69
const settings_json =
710
'{"fees":{"constant":10,"coefficient":2,"certificate":100},"discrimination":"production","block0_initial_hash":{"hash":"baf6b54817cf2a3e865f432c3922d28ac5be641e66662c66d445f141e409183e"},"block0_date":1586637936,"slot_duration":20,"time_era":{"epoch_start":0,"slot_start":0,"slots_per_epoch":180},"transaction_max_expiry_epochs":1}';
811

9-
describe("vote cast certificate tests", function () {
12+
describe("Inplace signing vote cast certificate tests", function () {
1013
it("public", async function () {
1114
const wallet = await import("wallet-js");
1215

@@ -17,8 +20,15 @@ describe("vote cast certificate tests", function () {
1720
8
1821
);
1922
let vote = new wallet.Vote(proposal, 0, new wallet.BlockDate(0, 1), 1, 1);
20-
let fragments = wallet.signVotes([vote], settings, private_key);
21-
assert(fragments.length == 1);
23+
let tx_builders = wallet.signVotes(
24+
[vote],
25+
settings,
26+
account_id,
27+
private_key
28+
);
29+
assert(tx_builders.length == 1);
30+
// get fragemnts
31+
fragments = tx_builders.map((tx_builder) => tx_builder.finalize_tx());
2232
});
2333

2434
it("private", async function () {
@@ -32,7 +42,53 @@ describe("vote cast certificate tests", function () {
3242
"bed88887abe0a84f64691fe0bdfa3daf1a6cd697a13f07ae07588910ce39c927"
3343
);
3444
let vote = new wallet.Vote(proposal, 0, new wallet.BlockDate(0, 1), 1, 1);
35-
let fragments = wallet.signVotes([vote], settings, private_key);
36-
assert(fragments.length == 1);
45+
let tx_builders = wallet.signVotes(
46+
[vote],
47+
settings,
48+
account_id,
49+
private_key
50+
);
51+
assert(tx_builders.length == 1);
52+
// get fragemnts
53+
fragments = tx_builders.map((tx_builder) => tx_builder.finalize_tx());
54+
});
55+
});
56+
57+
describe("Postponed signing vote cast certificate tests", function () {
58+
it("public", async function () {
59+
const wallet = await import("wallet-js");
60+
61+
let settings = new wallet.Settings(settings_json);
62+
let proposal = new wallet.Proposal(
63+
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
64+
2,
65+
8
66+
);
67+
let vote = new wallet.Vote(proposal, 0, new wallet.BlockDate(0, 1), 1, 1);
68+
let tx_builders = wallet.signVotes([vote], settings, account_id);
69+
assert(tx_builders.length == 1);
70+
// get fragemnts
71+
fragments = tx_builders.map((tx_builder) =>
72+
tx_builder.sign_tx(private_key).finalize_tx()
73+
);
74+
});
75+
76+
it("private", async function () {
77+
const wallet = await import("wallet-js");
78+
79+
let settings = new wallet.Settings(settings_json);
80+
let proposal = new wallet.Proposal(
81+
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
82+
4,
83+
8,
84+
"bed88887abe0a84f64691fe0bdfa3daf1a6cd697a13f07ae07588910ce39c927"
85+
);
86+
let vote = new wallet.Vote(proposal, 0, new wallet.BlockDate(0, 1), 1, 1);
87+
let tx_builders = wallet.signVotes([vote], settings, account_id);
88+
assert(tx_builders.length == 1);
89+
// get fragemnts
90+
fragments = tx_builders.map((tx_builder) =>
91+
tx_builder.sign_tx(private_key).finalize_tx()
92+
);
3793
});
3894
});

src/chain-wallet-libs/bindings/wallet-wasm-js/js/index.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class Vote {
4646
}
4747
module.exports.Vote = Vote;
4848

49-
function signVotes(votes, settings, privateKey) {
50-
let fragments = [];
49+
function signVotes(votes, settings, accountId, privateKey) {
50+
let tx_builders = [];
5151
for (let i = 0; i < votes.length; i++) {
5252
let vote = votes[i];
5353
let voteCast;
@@ -81,11 +81,16 @@ function signVotes(votes, settings, privateKey) {
8181
vote.expiration.slot,
8282
voteCast
8383
);
84-
let fragment = builder
85-
.build_tx(privateKey, vote.spendingCounter, vote.spendingCounterLane)
86-
.finalize_tx();
87-
fragments.push(fragment);
84+
let tx_builder = builder.build_tx(
85+
accountId,
86+
vote.spendingCounter,
87+
vote.spendingCounterLane
88+
);
89+
if (privateKey != undefined) {
90+
tx_builder = tx_builder.sign_tx(privateKey);
91+
}
92+
tx_builders.push(tx_builder);
8893
}
89-
return fragments;
94+
return tx_builders;
9095
}
9196
module.exports.signVotes = signVotes;

src/chain-wallet-libs/bindings/wallet-wasm-js/src/lib.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,27 @@ impl VoteCastTxBuilder {
6363
/// of the account.
6464
pub fn build_tx(
6565
mut self,
66-
hex_account: String,
66+
hex_account_id: String,
6767
counter: u32,
6868
lane: usize,
6969
) -> Result<VoteCastTxBuilder, JsValue> {
7070
self.0 = self
7171
.0
7272
.build_tx(
73+
hex_account_id,
74+
SpendingCounter::new(lane, counter).map_err(|e| JsValue::from(e.to_string()))?,
75+
)
76+
.map_err(|e| JsValue::from(e.to_string()))?;
77+
Ok(self)
78+
}
79+
80+
pub fn sign_tx(mut self, hex_account: String) -> Result<VoteCastTxBuilder, JsValue> {
81+
self.0 = self
82+
.0
83+
.sign_tx(
7384
hex::decode(hex_account)
7485
.map_err(|e| JsValue::from(e.to_string()))?
7586
.as_slice(),
76-
SpendingCounter::new(lane, counter).map_err(|e| JsValue::from(e.to_string()))?,
7787
)
7888
.map_err(|e| JsValue::from(e.to_string()))?;
7989
Ok(self)

src/chain-wallet-libs/bindings/wallet-wasm-js/src/utils.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
extern crate web_sys;
2+
3+
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
4+
// taken from:
5+
// https://rustwasm.github.io/book/game-of-life/debugging.html
6+
#[macro_export]
7+
macro_rules! log {
8+
( $( $t:tt )* ) => {
9+
web_sys::console::log_1(&format!( $( $t )* ).into());
10+
}
11+
}
12+
113
// taken from:
214
// https://github.com/input-output-hk/js-chain-libs/blob/cc463b59fdc64a4fff63f67901118f60b783520c/src/utils.rs#L12
315
#[macro_export]

src/chain-wallet-libs/wallet/src/transaction/builder.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,12 @@ impl<P: Payload> TransactionBuilder<P> {
101101
input: Input,
102102
witness_builder: B,
103103
) -> bool {
104-
match self.inputs.len().cmp(&255) {
105-
std::cmp::Ordering::Less => {
106-
self.inputs.push(input);
107-
self.witness_builders.push(Box::new(witness_builder));
108-
true
109-
}
110-
_ => false,
104+
if self.inputs().len() < 255 {
105+
self.inputs.push(input);
106+
self.witness_builders.push(Box::new(witness_builder));
107+
true
108+
} else {
109+
false
111110
}
112111
}
113112

src/jormungandr/testing/jormungandr-integration-tests/src/networking/p2p/public_traffic.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
use crate::networking::utils;
22
use hersir::{
33
builder::{NetworkBuilder, Node, Topology},
4-
config::{
5-
BlockchainBuilder, BlockchainConfiguration, NodeConfig, SpawnParams, WalletTemplateBuilder,
6-
},
4+
config::{BlockchainConfiguration, SpawnParams, WalletTemplateBuilder},
75
};
86
use jormungandr_automation::{
9-
jormungandr::{explorer::configuration::ExplorerParams, LogLevel},
7+
jormungandr::LogLevel,
108
testing::{ensure_nodes_are_in_sync, SyncWaitParams},
119
};
12-
13-
use jormungandr_lib::{
14-
interfaces::{Policy, PreferredListConfig, SlotDuration, TrustedPeer},
15-
time::{Duration, SystemTime},
16-
};
10+
use jormungandr_lib::time::Duration;
1711
use multiaddr::Multiaddr;
18-
use std::{
19-
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6},
20-
path::PathBuf,
21-
};
22-
use thor::{FragmentSender, FragmentVerifier};
12+
use thor::FragmentSender;
2313

2414
const GATEWAY: &str = "GATEWAY";
2515

@@ -221,7 +211,7 @@ pub fn test_public_node_cannot_publish() {
221211
.gossip_interval(Duration::new(1, 0))
222212
.allow_private_addresses(true)
223213
.public_address(address)
224-
.whitelist(whitelist.clone());
214+
.whitelist(whitelist);
225215

226216
params.override_settings(&mut public_node_config);
227217

@@ -368,7 +358,7 @@ pub fn test_public_node_synced_with_internal() {
368358
.gossip_interval(Duration::new(1, 0))
369359
.allow_private_addresses(true)
370360
.public_address(address)
371-
.whitelist(whitelist.clone());
361+
.whitelist(whitelist);
372362

373363
params.override_settings(&mut public_node_config);
374364

0 commit comments

Comments
 (0)