Skip to content

Commit 3cf123b

Browse files
codilion0o-de-lally
authored andcommitted
[cli] background tx submission service (#325)
Co-authored-by: 0o-de-lally <[email protected]>
1 parent 2091d45 commit 3cf123b

File tree

16 files changed

+377
-64
lines changed

16 files changed

+377
-64
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ jobs:
320320
cache-all-crates: true
321321
cache-on-failure: true
322322

323+
- uses: actions/[email protected]
324+
with:
325+
name: framework-build
326+
path: framework/
327+
323328
- name: twin
324329
working-directory: ./testsuites/twin
325330
run: cargo test --no-fail-fast

.gitignore

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,14 @@
22
# will have compiled files and executables
33
**/target/
44

5-
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6-
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
7-
Cargo.lock
8-
95
# These are backup files generated by rustfmt
106
**/*.rs.bk
117

128
# 0L
139
**/build
1410
**/doc
1511
**/framework_upgrade
16-
# # upgrade fixtures
17-
# **/framework/src/upgrade_fixtures/fixtures/upgrade*
12+
**/head.mrb
1813

1914
sccache.log
2015

framework/cached-packages/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn main() {
1818
prev_dir.join("libra-framework").join("sources").display()
1919
);
2020

21+
// TODO: make this run the libra binary if it is found in users $PATH
2122
ReleaseTarget::Head
2223
.create_release(
2324
false,

framework/cached-packages/src/libra_framework_sdk_builder.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![allow(dead_code)]
1414
#![allow(unused_imports)]
1515
#![allow(clippy::too_many_arguments, clippy::doc_lazy_continuation)]
16+
1617
use diem_types::{
1718
account_address::AccountAddress,
1819
transaction::{EntryFunction, TransactionPayload},
@@ -260,6 +261,10 @@ pub enum EntryFunctionCall {
260261
id: u64,
261262
},
262263

264+
/// testnet helper to allow testnet root account to set flip the boundary bit
265+
/// used for testing cli tools for polling and triggering
266+
EpochBoundarySmokeEnableTrigger {},
267+
263268
EpochBoundarySmokeTriggerEpoch {},
264269

265270
/// Only a Voucher of the validator can flip the unjail bit.
@@ -539,7 +544,7 @@ pub enum EntryFunctionCall {
539544
friend_account: AccountAddress,
540545
},
541546

542-
/// will only succesfully vouch if the two are not related by ancestry
547+
/// will only successfully vouch if the two are not related by ancestry
543548
/// prevents spending a vouch that would not be counted.
544549
/// to add a vouch and ignore this check use insist_vouch
545550
VouchVouchFor {
@@ -700,6 +705,7 @@ impl EntryFunctionCall {
700705
multisig_address,
701706
id,
702707
} => donor_voice_txs_vote_veto_tx(multisig_address, id),
708+
EpochBoundarySmokeEnableTrigger {} => epoch_boundary_smoke_enable_trigger(),
703709
EpochBoundarySmokeTriggerEpoch {} => epoch_boundary_smoke_trigger_epoch(),
704710
JailUnjailByVoucher { addr } => jail_unjail_by_voucher(addr),
705711
LibraCoinClaimMintCapability {} => libra_coin_claim_mint_capability(),
@@ -1509,6 +1515,23 @@ pub fn donor_voice_txs_vote_veto_tx(
15091515
))
15101516
}
15111517

1518+
/// testnet helper to allow testnet root account to set flip the boundary bit
1519+
/// used for testing cli tools for polling and triggering
1520+
pub fn epoch_boundary_smoke_enable_trigger() -> TransactionPayload {
1521+
TransactionPayload::EntryFunction(EntryFunction::new(
1522+
ModuleId::new(
1523+
AccountAddress::new([
1524+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1525+
0, 0, 0, 1,
1526+
]),
1527+
ident_str!("epoch_boundary").to_owned(),
1528+
),
1529+
ident_str!("smoke_enable_trigger").to_owned(),
1530+
vec![],
1531+
vec![],
1532+
))
1533+
}
1534+
15121535
pub fn epoch_boundary_smoke_trigger_epoch() -> TransactionPayload {
15131536
TransactionPayload::EntryFunction(EntryFunction::new(
15141537
ModuleId::new(
@@ -2353,7 +2376,7 @@ pub fn vouch_revoke(friend_account: AccountAddress) -> TransactionPayload {
23532376
))
23542377
}
23552378

2356-
/// will only succesfully vouch if the two are not related by ancestry
2379+
/// will only successfully vouch if the two are not related by ancestry
23572380
/// prevents spending a vouch that would not be counted.
23582381
/// to add a vouch and ignore this check use insist_vouch
23592382
pub fn vouch_vouch_for(friend_account: AccountAddress) -> TransactionPayload {
@@ -2730,6 +2753,16 @@ mod decoder {
27302753
}
27312754
}
27322755

2756+
pub fn epoch_boundary_smoke_enable_trigger(
2757+
payload: &TransactionPayload,
2758+
) -> Option<EntryFunctionCall> {
2759+
if let TransactionPayload::EntryFunction(_script) = payload {
2760+
Some(EntryFunctionCall::EpochBoundarySmokeEnableTrigger {})
2761+
} else {
2762+
None
2763+
}
2764+
}
2765+
27332766
pub fn epoch_boundary_smoke_trigger_epoch(
27342767
payload: &TransactionPayload,
27352768
) -> Option<EntryFunctionCall> {
@@ -3352,6 +3385,10 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy<EntryFunctionDecoderMa
33523385
"donor_voice_txs_vote_veto_tx".to_string(),
33533386
Box::new(decoder::donor_voice_txs_vote_veto_tx),
33543387
);
3388+
map.insert(
3389+
"epoch_boundary_smoke_enable_trigger".to_string(),
3390+
Box::new(decoder::epoch_boundary_smoke_enable_trigger),
3391+
);
33553392
map.insert(
33563393
"epoch_boundary_smoke_trigger_epoch".to_string(),
33573394
Box::new(decoder::epoch_boundary_smoke_trigger_epoch),

framework/libra-framework/sources/ol_sources/epoch_boundary.move

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ module diem_framework::epoch_boundary {
209209
// Just like a dream, you are not what you seem
210210
// Just like a prayer, no choice your voice can take me there...
211211
move_to(&framework_signer, BoundaryBit {
212-
closing_epoch: closing_epoch,
212+
closing_epoch,
213213
ready: true,
214214
})
215215
} else {
@@ -226,15 +226,12 @@ module diem_framework::epoch_boundary {
226226
/// by a user, would not cause a halt.
227227
public(friend) fun trigger_epoch(framework_signer: &signer)
228228
acquires BoundaryBit, BoundaryStatus {
229-
// COMMIT NOTE: there's no reason to gate this, if th trigger is not
230-
// ready (which only happens on Main and Stage, then user will get an error)
231-
// assert!(!testnet::is_testnet(), ETRIGGER_EPOCH_MAINNET);
232229
// must get root permission from governance.move
233230
system_addresses::assert_diem_framework(framework_signer);
234-
let _ = can_trigger(); // will abort if false
231+
let _ = assert_can_trigger(); // will abort if false
235232

236233
// update the state and flip the Bit
237-
// note we are using the 0x0 address for BoundaryBit
234+
// note we are using the 0x1 address for BoundaryBit
238235
let state = borrow_global_mut<BoundaryBit>(@ol_framework);
239236
state.ready = false;
240237

@@ -253,16 +250,45 @@ module diem_framework::epoch_boundary {
253250
epoch_boundary(framework_signer, state.closing_epoch, 0);
254251
}
255252

253+
/// testnet helper to allow testnet root account to set flip the boundary bit
254+
/// used for testing cli tools for polling and triggering
255+
public entry fun smoke_enable_trigger(core_resource: &signer)
256+
acquires BoundaryBit {
257+
// cannot call this on mainnet
258+
// only for smoke testing
259+
assert!(testnet::is_not_mainnet(), ETRIGGER_EPOCH_UNAUTHORIZED);
260+
// core_resource account is the the tesnet account with root permissions
261+
system_addresses::assert_core_resource(core_resource);
262+
let state = borrow_global_mut<BoundaryBit>(@ol_framework);
263+
state.closing_epoch = reconfiguration::get_current_epoch();
264+
state.ready = true;
265+
}
266+
267+
256268
#[view]
257-
/// check to see if the epoch BoundaryBit is true
258-
public fun can_trigger(): bool acquires BoundaryBit {
269+
/// API view for triggering which does not abort
270+
public fun can_trigger():bool acquires BoundaryBit {
271+
let state = borrow_global_mut<BoundaryBit>(@ol_framework);
272+
if (state.ready &&
273+
// greater than or equal because in case there is an epoch change due to an epoch bump in
274+
// testnet Twin tools, or a rescue operation.
275+
state.closing_epoch <= reconfiguration::get_current_epoch()){
276+
return true
277+
};
278+
279+
false
280+
}
281+
282+
/// assert and abort with failure reason for trigger
283+
fun assert_can_trigger(): bool acquires BoundaryBit {
259284
let state = borrow_global_mut<BoundaryBit>(@ol_framework);
260285
assert!(state.ready, ETRIGGER_NOT_READY);
261-
// greater than, in case there is an epoch change due to an epoch bump in
286+
// greater than or equal because in case there is an epoch change due to an epoch bump in
262287
// testnet Twin tools, or a rescue operation.
263288
assert!(state.closing_epoch <= reconfiguration::get_current_epoch(),
264289
ENOT_SAME_EPOCH);
265-
true
290+
291+
can_trigger()
266292
}
267293

268294
// This function handles the necessary migrations that occur at the epoch boundary
@@ -272,9 +298,10 @@ module diem_framework::epoch_boundary {
272298
migrations::execute(framework);
273299
}
274300

275-
// Contains all of 0L's business logic for end of epoch.
276-
// This removed business logic from reconfiguration.move
277-
// and prevents dependency cycling.
301+
/// Contains all of 0L's business logic for end of epoch.
302+
/// This removed business logic from reconfiguration.move
303+
/// and prevents dependency cycling.
304+
// TODO: do we need closing_epoch if there is no depedency cycling with reconfiguration::
278305
public(friend) fun epoch_boundary(root: &signer, closing_epoch: u64, epoch_round: u64)
279306
acquires BoundaryStatus {
280307
print(&string::utf8(b"EPOCH BOUNDARY BEGINS"));

framework/releases/head.mrb

-870 KB
Binary file not shown.

tools/query/src/chain_queries.rs

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
33
use crate::query_view::{self, get_view};
44
use anyhow::Context;
5-
use diem_sdk::rest_client::{diem_api_types::ViewRequest, Client};
6-
use libra_types::type_extensions::client_ext::entry_function_id;
5+
use diem_sdk::rest_client::Client;
76

87
/// Retrieves the current epoch from the blockchain.
98
pub async fn get_epoch(client: &Client) -> anyhow::Result<u64> {
@@ -21,29 +20,7 @@ pub async fn get_epoch(client: &Client) -> anyhow::Result<u64> {
2120
Ok(num)
2221
}
2322

24-
/// helper to get libra balance at a SlowWalletBalance type which shows
25-
/// total balance and the unlocked balance.
26-
pub async fn get_tower_difficulty(client: &Client) -> anyhow::Result<(u64, u64)> {
27-
let slow_balance_id = entry_function_id("tower_state", "get_difficulty")?;
28-
let request = ViewRequest {
29-
function: slow_balance_id,
30-
type_arguments: vec![],
31-
arguments: vec![],
32-
};
33-
34-
let res = client.view(&request, None).await?.into_inner();
35-
36-
// TODO: Gross.
37-
let difficulty: u64 =
38-
serde_json::from_value::<String>(res.first().context("no difficulty returned")?.clone())?
39-
.parse()?;
40-
let security: u64 = serde_json::from_value::<String>(
41-
res.get(1).context("no security param returned")?.clone(),
42-
)?
43-
.parse()?;
44-
45-
Ok((difficulty, security))
46-
}
23+
// COMMIT NOTE: deprecated tower functions
4724

4825
/// Retrieves the ID of the next governance proposal.
4926
pub async fn get_next_governance_proposal_id(client: &Client) -> anyhow::Result<u64> {
@@ -115,3 +92,12 @@ pub async fn get_height(client: &Client) -> anyhow::Result<u64> {
11592

11693
Ok(height)
11794
}
95+
96+
/// Retrieves the current blockchain height.
97+
pub async fn epoch_over_can_trigger(client: &Client) -> anyhow::Result<bool> {
98+
let res = get_view(client, "0x1::epoch_boundary::can_trigger", None, None).await?;
99+
100+
let value: Vec<bool> = serde_json::from_value(res)?;
101+
102+
Ok(value[0])
103+
}

tools/txs/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
pub mod constants;
22
pub mod generic_tx;
33
pub mod publish;
4+
pub mod stream;
45
pub mod submit_transaction;
56
pub mod transfer;
67
pub mod txs_cli;
78
pub mod txs_cli_community;
89
pub mod txs_cli_governance;
10+
pub mod txs_cli_stream;
911
pub mod txs_cli_user;
1012
pub mod txs_cli_vals;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#[derive(clap::Args)]
2+
pub struct PofBidArgs {
3+
#[clap(short, long)]
4+
pub net_reward: u64,
5+
6+
#[clap(short, long)]
7+
pub test_private_key: Option<String>,
8+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use diem_logger::info;
2+
use diem_types::transaction::TransactionPayload;
3+
use libra_cached_packages::libra_stdlib;
4+
use libra_types::exports::Client;
5+
use std::borrow::BorrowMut;
6+
use std::sync::mpsc::Sender;
7+
use std::thread;
8+
use std::time::Duration;
9+
10+
pub fn epoch_tickle_poll(mut tx: Sender<TransactionPayload>, client: Client, delay_secs: u64) {
11+
println!("polling epoch boundary");
12+
let handle = thread::spawn(move || loop {
13+
let rt = tokio::runtime::Builder::new_current_thread()
14+
.enable_all()
15+
.build()
16+
.unwrap();
17+
18+
// TODO: make the client borrow instead of clone
19+
let res = rt.block_on(libra_query::chain_queries::epoch_over_can_trigger(
20+
&client.clone(),
21+
));
22+
23+
match res {
24+
Ok(true) => {
25+
let func = libra_stdlib::diem_governance_trigger_epoch();
26+
27+
tx.borrow_mut().send(func).unwrap();
28+
}
29+
_ => {
30+
info!("Not ready to call epoch.")
31+
}
32+
}
33+
34+
thread::sleep(Duration::from_secs(delay_secs));
35+
});
36+
handle.join().expect("cannot poll for epoch boundary");
37+
}

0 commit comments

Comments
 (0)