Skip to content

Commit

Permalink
work on simplifying hard fork script since we have no miners anyway
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroProofs committed Apr 6, 2024
1 parent 6ffd09d commit 2d85438
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 18 deletions.
4 changes: 2 additions & 2 deletions aiken.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ requirements = []
source = "github"

[etags]
"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1710892378, nanos_since_epoch = 346803000 }, "d7aadd4a9b25589bd6d5e3bbedcd809cdf97fe3eddb365cf89cd6ac6bc829643"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1710892378, nanos_since_epoch = 160936000 }, "4fe5fcedb7f1061f9e9c25d1811cba7a5b452be6a3669a8b81e1ac0a44aa3f9e"]
"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1712437807, nanos_since_epoch = 174285000 }, "d7aadd4a9b25589bd6d5e3bbedcd809cdf97fe3eddb365cf89cd6ac6bc829643"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1712437807, nanos_since_epoch = 11046000 }, "2a710731e0127ec3e21c6c3962a0254c98602e7428b33fc4fcaa67ab368ce1b1"]
11 changes: 9 additions & 2 deletions lib/fortuna/types.ak
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ pub type MineState {
current_posix_time: Int,
}

pub type NominatedVote {
/// The current amount of miner votes for the current nomination token.
vote_count: Int,
/// The block height where the nomination token is burned.
vote_deadline: Int,
}

pub type ExtraState {
nominated_hash: Option<ByteArray>,
extra: Data,
new_spend_votes: Option<NominatedVote>,
merkle: ByteArray,
extra: Data,
}
9 changes: 2 additions & 7 deletions lib/hardfork.ak
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ use hardfork/hftypes.{
MinerLockState, NftState, NotForked, UserLock,
}
use hardfork/params.{
hardfork_block_height, miner_hardfork_threshold, tuna_count_blocks_from,
hard_fork_state_token, hardfork_block_height, lock_state_token,
miner_hardfork_threshold, miner_lock_state_token, tuna_count_blocks_from,
tuna_hardfork_threshold_denominator, tuna_hardfork_threshold_numerator,
}

pub const miner_lock_state_token: ByteArray = "miner_lock_state"

pub const lock_state_token: ByteArray = "lock_state"

pub const hard_fork_state_token: ByteArray = "hfs"

/// Check for the proper initialization of the hard fork state
pub fn initialize(
// Input
Expand Down
8 changes: 8 additions & 0 deletions lib/hardfork/params.ak
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ pub const tuna_count_blocks_from = 1000
pub const tuna_hardfork_version = 2

pub const hardfork_block_height = 100

pub const miner_lock_state_token = "miner_lock_state"

pub const lock_state_token = "lock_state"

pub const hard_fork_state_token = "hfs"

pub const hard_fork_merkle_root = ""
9 changes: 3 additions & 6 deletions validators/fork.ak
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use hardfork/hftypes.{
ForkDatum, Forked, HardForkState, LockAction, LockState, MinerLockState,
NotForked,
}
use hardfork/params.{lock_state_token, miner_lock_state_token}

type NftForkAction {
/// Only run once to initialize the nft tokens
Expand Down Expand Up @@ -119,7 +120,7 @@ validator(init_utxo_ref: OutputReference, fortuna_v1_hash: ByteArray) {
quantity_of(
input.output.value,
own_policy,
hf.miner_lock_state_token,
miner_lock_state_token,
) == 1
},
)
Expand Down Expand Up @@ -172,11 +173,7 @@ validator(init_utxo_ref: OutputReference, fortuna_v1_hash: ByteArray) {
list.find(
transaction.reference_inputs,
fn(input) {
quantity_of(
input.output.value,
own_policy,
hf.lock_state_token,
) == 1
quantity_of(input.output.value, own_policy, lock_state_token) == 1
},
)

Expand Down
127 changes: 127 additions & 0 deletions validators/simplerfork.ak
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use aiken/builtin
use aiken/dict
use aiken/list
use aiken/transaction.{
InlineDatum, Output, OutputReference, ScriptContext, Transaction,
} as tx
use aiken/transaction/credential.{Address, Inline, ScriptCredential}
use aiken/transaction/value
use fortuna
use fortuna/types.{ExtraState, MineState, State, Statev2}
use fortuna/utils
use hardfork/params.{
hard_fork_merkle_root, hardfork_block_height, lock_state_token,
}

/// Simplified fork with only 2 actions. HardFork current tuna v1 version to v2 version
/// and Lock action to lock v1 tokens and mint v2 tokens. This is simpler version that does not have miners'
/// input in the hardfork action. This is mainly because there are no current miners anyway.
type NftForkAction {
/// This action is only run once and it sets up the ability to convert v1 tuna tokens to v2 tuna tokens
HardFork { lock_output_index: Int }

Lock { lock_output_index: Int, lock_state_input_ref: OutputReference }
}

/// Ensures that maximum lockable tuna is equal to emitted tuna at block height
type LockState {
block_height: Int,
current_locked_tuna: Int,
}

validator(init_utxo_ref: OutputReference, fortuna_v1_hash: ByteArray) {
fn nft_fork(redeemer: Data, ctx: ScriptContext) -> Bool {
let ScriptContext { transaction, purpose } = ctx

when purpose is {
tx.Mint(own_policy) -> {
let Transaction { withdrawals, .. } = transaction

let own_withdrawal = Inline(ScriptCredential(own_policy))

// Fork Mint(0) requirement: Withdrawal script is present
dict.has_key(withdrawals, own_withdrawal)
}

tx.WithdrawFrom(stake_cred) -> {
expect action: NftForkAction = redeemer

expect Inline(ScriptCredential(own_policy)) = stake_cred

when action is {
HardFork { lock_output_index } -> {
let Transaction { inputs, reference_inputs, outputs, mint, .. } =
transaction

// Step 1: Pull out script context information to validate on
// This include inputs, reference inputs, outputs, and minted tokens
let Output { address, datum, value, .. } =
utils.list_at(outputs, lock_output_index)

expect Some(_) =
list.find(
inputs,
fn(input) { input.output_reference == init_utxo_ref },
)

let v1_miner_ref =
utils.resolve_output_reference(reference_inputs, init_utxo_ref)

expect [(_, 1)] =
mint
|> value.from_minted_value
|> value.tokens(own_policy)
|> dict.to_list

// Step 2: Extract input state from inputs
// In this case only block_number from v1_miner_ref is needed
expect State { block_number, .. }: State =
v1_miner_ref.datum |> utils.get_inline_datum

// Step 3: Created expected output state
let expected_lock_state =
InlineDatum(
LockState { block_height: block_number, current_locked_tuna: 0 },
)

let expected_lock_value =
value.from_asset(own_policy, lock_state_token, 1)

// Step 4: Validate that the transitioning states are correct
and {
// Validate reference input state
v1_miner_ref.value
|> value.quantity_of(fortuna_v1_hash, fortuna.master_token_name)
|> builtin.equals_integer(1),
// Validate output state
address == Address(ScriptCredential(own_policy), None),
datum == expected_lock_state,
value
|> value.without_lovelace
|> builtin.equals_data(expected_lock_value),
}
}

Lock { .. } -> todo
}
}

_ -> False
}
}

fn fork(_datum, _redeemer, ctx: ScriptContext) -> Bool {
let ScriptContext { transaction, purpose } = ctx

expect tx.Spend(own_ref) = purpose

let Transaction { inputs, withdrawals, .. } = transaction

let own_input = utils.resolve_output_reference(inputs, own_ref)

let own_withdrawal = Inline(own_input.address.payment_credential)

// Fork Spend(0) requirement: Withdrawal script is present
dict.has_key(withdrawals, own_withdrawal)
}
}
2 changes: 1 addition & 1 deletion validators/tunav2.ak
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use fortuna/types.{ExtraState, MineState, Statev2}
use fortuna/utils.{
get_inline_datum, list_at, quantity_of, resolve_output_reference,
}
use hardfork.{hard_fork_state_token}
use hardfork/hftypes.{ForkDatum, NftState}
use hardfork/params.{hard_fork_state_token}

type TunaAction {
Genesis
Expand Down

0 comments on commit 2d85438

Please sign in to comment.