Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ jobs:
uses: dsherret/rust-toolchain-file@3551321aa44dd44a0393eb3b6bdfbc5d25ecf621 # v1

- name: Install cargo-audit
run: cargo install cargo-audit
run: cargo install cargo-audit --locked

- name: Run security audit
run: make audit
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ developer:
echo "Cargo version: $$(cargo --version)"; \
echo "Installing development tools..."; \
$(MAKE) coverage-setup; \
cargo install cargo-audit --quiet || echo "WARNING: cargo-audit installation failed or already installed"; \
cargo install cargo-audit --locked --quiet || echo "WARNING: cargo-audit installation failed or already installed"; \
Comment thread
Srayman marked this conversation as resolved.
echo "Installing script dependencies..."; \
if ! command -v jq > /dev/null 2>&1; then \
echo "Installing jq..."; \
Expand Down
20 changes: 15 additions & 5 deletions keetanetwork-block/src/testing.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Deterministic account, operation, and builder factories shared by
//! every Keetanetwork test suite.
//! Account, operation, and builder factories shared by every Keetanetwork
//! test suite.

use alloc::sync::Arc;

use keetanetwork_account::{Account, Accountable, GenericAccount, KeyED25519, KeyPairType, Keyable};
use keetanetwork_account::{Account, Accountable, GenericAccount, KeyED25519, KeyPairType, Keyable, Seed};
use keetanetwork_crypto::prelude::IntoSecret;

use crate::amount::Amount;
Expand All @@ -12,17 +12,27 @@ use crate::operation::Send;
use crate::signer::AccountRef;
use crate::time::BlockTime;

fn base_account(seed_byte: u8) -> Account<KeyED25519> {
let seed = [seed_byte; 32].into_secret();
fn seeded_account(seed: Seed) -> Account<KeyED25519> {
Account::<KeyED25519>::try_from(Accountable::KeyAndType(Keyable::Seed((seed, 0)), KeyPairType::ED25519))
.expect("test account construction must succeed")
}

fn base_account(seed_byte: u8) -> Account<KeyED25519> {
seeded_account([seed_byte; 32].into_secret())
}

/// A deterministic ed25519 keyed account.
pub fn generate_ed25519_ref(seed_byte: u8) -> AccountRef {
Arc::new(GenericAccount::Ed25519(base_account(seed_byte)))
}

/// A randomly keyed ed25519 account, for tests whose contract is "any
/// account" rather than a particular key.
pub fn random_ed25519_ref() -> AccountRef {
let seed = Account::<KeyED25519>::generate_random_seed().expect("test seed generation must succeed");
Arc::new(GenericAccount::Ed25519(seeded_account(seed)))
}

/// A deterministic identifier account derived from a seed-byte owner.
///
/// Equivalent to `derive_identifier(&generate_ed25519_ref(seed_byte), ..)`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package network.keeta.wasi;

import java.util.List;

/**
* Factory invoked mid-transmit when {@link TransmitOptions} carries one: build
* and sign the block paying the fee the temporary-round {@code staple}
* demands, honoring the {@code feeTokenPriority} preference. Return
* {@code null} to pay nothing. See
* {@link UserClient#buildFeeBlock(VoteStaple, Account, Account, List)} for the
* common implementation.
*/
@FunctionalInterface
public interface GenerateFeeBlock {
Block.SignedBlock generate(UserClient client, VoteStaple staple, List<Account> feeTokenPriority);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package network.keeta.wasi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Publish-time options for {@link UserClient#transmit(List, TransmitOptions)}.
* Fee payment is a {@link GenerateFeeBlock} factory.
* {@link #withFeeSigner(Account)} and
* {@link #withFeeBlockFrom(Account, Account)} cover the common shapes.
*/
public final class TransmitOptions {
private final List<Account> feeTokenPriority = new ArrayList<>();
private GenerateFeeBlock generateFeeBlock;

private TransmitOptions() {
}

/** Options paying no fee: a vote requiring one fails with {@code FEE_REQUIRED}. */
public static TransmitOptions defaults() {
return new TransmitOptions();
}

/**
* Append a token to the fee-token preference order, highest priority
* first, used when a fee is payable in several tokens.
*/
public TransmitOptions addFeeTokenPriority(Account token) {
this.feeTokenPriority.add(token);
return this;
}

/** Pay any required fee from {@code signer}, signing for itself. */
public TransmitOptions withFeeSigner(Account signer) {
return withFeeBlockFrom(signer, signer);
}

/**
* Pay any required fee from {@code account}, signed by {@code signer}
* (delegated signing, e.g. a storage account whose owner signs). For a
* payer that signs for itself, prefer {@link #withFeeSigner(Account)}.
*/
public TransmitOptions withFeeBlockFrom(Account account, Account signer) {
this.generateFeeBlock = (client, staple, priority) -> client.buildFeeBlock(staple, account, signer, priority);
return this;
}

/** Install a hand-written fee-block factory for exotic payment flows. */
public TransmitOptions withGenerateFeeBlock(GenerateFeeBlock factory) {
this.generateFeeBlock = factory;
return this;
}

List<Account> feeTokenPriority() {
return Collections.unmodifiableList(feeTokenPriority);
}

GenerateFeeBlock generateFeeBlock() {
return generateFeeBlock;
}
}
Loading
Loading