Skip to content

Commit

Permalink
feat: finish up hard fork validation, onto tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroProofs committed Oct 18, 2023
1 parent 0371f99 commit 19d4ea9
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 15 deletions.
5 changes: 2 additions & 3 deletions aiken.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

[[requirements]]
name = "aiken-lang/stdlib"
version = "main"
version = "1.6.0"
source = "github"

[[packages]]
name = "aiken-lang/stdlib"
version = "main"
version = "1.6.0"
requirements = []
source = "github"

[etags]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1696451950, nanos_since_epoch = 735752000 }, "a721cf2738274f806efefb5a33c6ff9ae049476f0d45a42049b71793949f4d1d"]
2 changes: 1 addition & 1 deletion aiken.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ platform = 'github'

[[dependencies]]
name = 'aiken-lang/stdlib'
version = 'main'
version = '1.6.0'
source = 'github'
179 changes: 176 additions & 3 deletions lib/hardfork.ak
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hardfork/hftypes.{
FailedFork, ForkDatum, Forked, HardForkState, LockAction, LockInit, LockMore,
LockState, MinerLockInit, MinerLockMore, MinerLockState, NftState, NotForked,
}
use hardfork/params.{hardfork_threshold}
use hardfork/params.{miner_hardfork_threshold, tuna_hardfork_threshold}

pub const miner_lock_state_token: ByteArray = "miner_lock_state"

Expand Down Expand Up @@ -686,6 +686,7 @@ pub fn hard_fork(
v2_miner_output: Int,
transaction: Transaction,
own_policy: ByteArray,
ref_locked_tuna: Int,
) -> Bool {
let Transaction { inputs, outputs, mint, .. } = transaction

Expand Down Expand Up @@ -833,7 +834,9 @@ pub fn hard_fork(
// Miner lock state is updated correctly
out_locked_tuna == user_locked_tuna + locked_tuna,
out_block_signals == block_signals + 1,
out_block_signals >= hardfork_threshold,
// Thresholds are met
out_block_signals >= miner_hardfork_threshold,
out_locked_tuna + ref_locked_tuna >= tuna_hardfork_threshold,
// Miner lock value is correct
value.without_lovelace(out_miner_lock_value) == value.without_lovelace(
miner_lock_value,
Expand All @@ -852,7 +855,177 @@ pub fn hard_fork(
}
}

MinerLockMore { fortuna_v1_output, nft_input_ref, output_key_index } -> todo
MinerLockMore { fortuna_v1_output, nft_input_ref, output_key_index } -> {
expect [] =
mint
|> value.from_minted_value
|> value.tokens(own_policy)
|> dict.to_list

// Handle getting input state
expect [script_input1, script_input2, script_input3] = script_inputs

let (hard_fork_state_input, miner_lock_input, nft_input) =
if script_input1.output_reference == hard_fork_state_input {
if script_input2.output_reference == nft_input_ref {
(script_input1.output, script_input3.output, script_input2.output)
} else {
(script_input1.output, script_input2.output, script_input3.output)
}
} else if script_input2.output_reference == hard_fork_state_input {
if script_input1.output_reference == nft_input_ref {
(script_input2.output, script_input3.output, script_input1.output)
} else {
(script_input2.output, script_input1.output, script_input3.output)
}
} else {
if script_input1.output_reference == nft_input_ref {
(script_input3.output, script_input2.output, script_input1.output)
} else {
(script_input3.output, script_input1.output, script_input2.output)
}
}

let Output { value: miner_lock_value, datum: miner_lock_datum, .. } =
miner_lock_input

expect InlineDatum(miner_lock_datum) = miner_lock_datum

expect MinerLockState { locked_tuna, block_signals }: ForkDatum =
miner_lock_datum

let Output { value: nft_value, datum: nft_datum, .. } = nft_input

expect InlineDatum(nft_datum) = nft_datum

expect NftState { nft_key }: ForkDatum = nft_datum

let Output {
value: hard_fork_state_value,
datum: hard_fork_state_datum,
..
} = hard_fork_state_input

expect InlineDatum(hard_fork_state_datum) = hard_fork_state_datum

expect HardForkState {
status: NotForked,
fork_block_height,
fortuna_v2_hash,
}: ForkDatum = hard_fork_state_datum

// Handle getting output states
let fortuna_v1_output = list_at(outputs, fortuna_v1_output)

let Output { value: fortuna_v1_value, datum: fortuna_v1_datum, .. } =
fortuna_v1_output

expect InlineDatum(fortuna_v1_datum) = fortuna_v1_datum

expect State { block_number, .. }: State = fortuna_v1_datum

let (out_miner_lock_value, out_miner_lock_datum, out_nft_value, nft_datum) =
get_output_lock_state(
outputs,
lock_output_index,
nft_output_index,
own_address,
)

expect MinerLockState {
locked_tuna: out_locked_tuna,
block_signals: out_block_signals,
}: ForkDatum = out_miner_lock_datum

expect NftState { nft_key: out_nft_key }: ForkDatum = nft_datum

let hfs_output = list_at(outputs, hardfork_output_index)

let Output { address, value: out_hfs_value, datum: out_hfs_datum, .. } =
hfs_output

expect address == own_address
//
expect InlineDatum(out_hfs_datum) = out_hfs_datum

expect HardForkState {
status: Forked,
fork_block_height: out_fork_block_height,
fortuna_v2_hash: out_fortuna_v2_hash,
}: ForkDatum = out_hfs_datum

let fortuna_v2 = list_at(outputs, v2_miner_output)

let Output {
address,
value: fortuna_v2_value,
datum: fortuna_v2_datum,
..
} = fortuna_v2

expect
address == Address {
payment_credential: ScriptCredential(fortuna_v2_hash),
stake_credential: None,
}
expect InlineDatum(fortuna_v2_datum) = fortuna_v2_datum

let user_locked_tuna =
quantity_of(out_nft_value, fortuna_v1_hash, fortuna.token_name) - quantity_of(
nft_value,
fortuna_v1_hash,
fortuna.token_name,
)

let proof_of_ownership = list_at(outputs, output_key_index)

let Output { value: proof_of_ownership_value, .. } = proof_of_ownership

and {
// Miner mined a valid fortuna v1 block
quantity_of(
fortuna_v1_value,
fortuna_v1_hash,
fortuna.master_token_name,
) == 1,
// Hard fork state is run at correct block number
fork_block_height == block_number,
// Fortuna v2 Output state is correct
fortuna_v2_datum == fortuna_v1_datum,
// Fortuna v2 Output value is correct
utils.value_has_nft_and_lovelace(
fortuna_v2_value,
fortuna_v2_hash,
fortuna.master_token_name,
),
// nft key at output datum has same token name as nft key
nft_key == out_nft_key,
quantity_of(proof_of_ownership_value, own_policy, nft_key) == 1,
// Miner locked at least some tuna
user_locked_tuna > 0,
// Miner lock state is updated correctly
out_locked_tuna == user_locked_tuna + locked_tuna,
out_block_signals == block_signals + 1,
// Thresholds are met
out_block_signals >= miner_hardfork_threshold,
out_locked_tuna + ref_locked_tuna >= tuna_hardfork_threshold,
// Miner lock value is correct
value.without_lovelace(out_miner_lock_value) == value.without_lovelace(
miner_lock_value,
),
quantity_of(out_miner_lock_value, own_policy, miner_lock_state_token) == 1,
// Hard fork state is updated correctly
out_fork_block_height == fork_block_height,
out_fortuna_v2_hash == fortuna_v2_hash,
// Hard fork state value is correct
quantity_of(hard_fork_state_value, own_policy, hard_fork_state_token) == 1,
utils.value_has_nft_and_lovelace(
out_hfs_value,
own_policy,
hard_fork_state_token,
),
}
}

_ -> False
}
Expand Down
4 changes: 3 additions & 1 deletion lib/hardfork/params.ak
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
pub const hardfork_threshold = 2
pub const miner_hardfork_threshold = 2

pub const tuna_hardfork_threshold = 2
Loading

0 comments on commit 19d4ea9

Please sign in to comment.