Skip to content

Commit 61ad521

Browse files
committed
exec/gas accounting
1 parent 7909a9f commit 61ad521

13 files changed

Lines changed: 243 additions & 60 deletions

File tree

ex/lib/consensus/fabric_gen.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ defmodule FabricGen do
311311
entry_epoch: div(entry.header.height, 100_000),
312312
}
313313

314-
txus = Enum.map(entry.txs, & Map.merge(&1, %{tx_cost: TX.exec_cost(0, &1), tx_size: byte_size(RDB.vecpak_encode(&1))}))
314+
txus = Enum.map(entry.txs, & Map.merge(&1, %{tx_cost: TX.exec_cost(0, &1), tx_size: byte_size(RDB.vecpak_encode(&1)),
315+
tx_historical_cost: TX.historical_cost(&1) }))
315316
{rtx, m, m_rev, l, root_receipts, root_contractstate} = RDB.apply_entry(db, next_entry_trimmed_map,
316317
Application.fetch_env!(:ama, :trainer_pk), Application.fetch_env!(:ama, :trainer_sk), txus,
317318
!!Application.fetch_env!(:ama, :testnet), Map.keys(Application.fetch_env!(:ama, :keys_by_pk))

ex/lib/consensus/models/attestation.ex

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
defmodule Attestation do
22
_ = """
33
attestation {
4+
hash: <>,
45
entry_hash: <>,
6+
entry_height: <>,
57
mutations_hash: <>,
8+
root_receipts: <>,
9+
root_contractstate: <>,
10+
root_entries: <>,
611
signer: <>,
712
signature: <entry_hash,mutations_hash>,
813
}
914
"""
15+
#@fields [:hash, :signature, :attestation, :signer, :entry_hash, :entry_height, :mutations_hash, :root_receipts, :root_contractstate, :root_entries]
1016
@fields [:entry_hash, :mutations_hash, :signer, :signature]
17+
@fields_attestation [:signer, :entry_hash, :entry_height, :root_receipts, :root_contractstate, :root_entries]
1118

1219
def pack_for_db(attestation_unpacked) when is_binary(attestation_unpacked) do attestation_unpacked end
1320
def pack_for_db(attestation_unpacked) do
@@ -16,7 +23,7 @@ defmodule Attestation do
1623
|> RDB.vecpak_encode()
1724
end
1825

19-
def sign(sk, entry_hash, mutations_hash) do
26+
def sign(sk, entry_hash, entry_height, mutations_hash, root_receipts, root_contractstate, root_entries) do
2027
pk = BlsEx.get_public_key!(sk)
2128
signature = BlsEx.sign!(sk, <<entry_hash::binary, mutations_hash::binary>>, BLS12AggSig.dst_att())
2229
%{
@@ -38,8 +45,11 @@ defmodule Attestation do
3845
if !is_binary(a.signer), do: throw(%{error: :signer_not_binary})
3946
if byte_size(a.signer) != 48, do: throw(%{error: :signer_not_48_bytes})
4047

41-
claim = <<a.entry_hash::binary, a.mutations_hash::binary>>
42-
if !BlsEx.verify?(a.signer, a.signature, claim, BLS12AggSig.dst_att()), do: throw(%{error: :invalid_signature})
48+
#if DB.Chain.height() >= RDBProtocol.forkheight() do
49+
#else
50+
claim = <<a.entry_hash::binary, a.mutations_hash::binary>>
51+
if !BlsEx.verify?(a.signer, a.signature, claim, BLS12AggSig.dst_att()), do: throw(%{error: :invalid_signature})
52+
#end
4353

4454
%{error: :ok, attestation: a}
4555
catch

ex/lib/consensus/models/entry.ex

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,6 @@ defmodule Entry do
5555

5656
@fields [:header, :hash, :signature, :txs, :mask, :mask_size, :mask_set_size]
5757
@fields_header [:height, :prev_hash, :slot, :prev_slot, :signer, :dr, :vr, :root_tx, :root_validator]
58-
@forkheight 412_00009
59-
60-
def forkheight() do
61-
@forkheight
62-
end
63-
64-
def forkheight2() do
65-
@forkheight+@forkheight+111000
66-
end
6758

6859
def unpack_from_db(nil), do: nil
6960
def unpack_from_db(entry_packed) do

ex/lib/consensus/models/entry_genesis.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ defmodule EntryGenesis do
193193
RocksDB.put("bic:epoch:segment_vr_hash", Blake3.hash(vr), %{rtx: rtx, cf: cf.contractstate})
194194

195195
Enum.each(Application.fetch_env!(:ama, :keys), fn(key)->
196-
RocksDB.put("account:#{key.pk}:balance:AMA", "1001000000000", %{rtx: rtx, cf: cf.contractstate})
196+
RocksDB.put("account:#{key.pk}:balance:AMA", "10300300123456789", %{rtx: rtx, cf: cf.contractstate})
197197
RocksDB.put("account:#{key.pk}:attribute:pop", key.pop, %{rtx: rtx, cf: cf.contractstate})
198198
end)
199199
rtx = RocksDB.transaction_commit(rtx)

ex/lib/consensus/models/tx.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ defmodule TX do
152152
BIC.Coin.to_cents( 1 + div(bytes, 1024) * 1 )
153153
end
154154

155+
def historical_cost(txu) do
156+
min(
157+
RDBProtocol.ama_1_cent(),
158+
max(
159+
RDBProtocol.ama_1_cent(),
160+
RDBProtocol.cost_per_byte_historical() * byte_size(RDB.vecpak_encode(txu.tx))))
161+
end
162+
155163
def action(%{tx: %{actions: [action|_]}}), do: action
156164
def action(%{tx: %{action: action}}), do: action
157165
end

ex/lib/native/rdb.ex

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,44 @@ defmodule RDB do
5454
def bintree_root_prove(_propslist, _key), do: :erlang.nif_error(:nif_not_loaded)
5555
def bintree_root_verify(_proof, _ns, _key, _value), do: :erlang.nif_error(:nif_not_loaded)
5656
def bintree_contractstate_root_prove(_db, _key), do: :erlang.nif_error(:nif_not_loaded)
57+
58+
def protocol_constants(), do: :erlang.nif_error(:nif_not_loaded)
59+
end
60+
61+
defmodule RDBProtocol do
62+
def reserve_ama_per_tx() do
63+
const = :persistent_term.get({ProtocolConstant, :reserve_ama_per_tx}, nil)
64+
if const do const else
65+
const = RDB.protocol_constants().reserve_ama_per_tx
66+
:persistent_term.put({ProtocolConstant, :reserve_ama_per_tx}, const)
67+
const
68+
end
69+
end
70+
71+
def cost_per_byte_historical() do
72+
const = :persistent_term.get({ProtocolConstant, :cost_per_byte_historical}, nil)
73+
if const do const else
74+
const = RDB.protocol_constants().cost_per_byte_historical
75+
:persistent_term.put({ProtocolConstant, :cost_per_byte_historical}, const)
76+
const
77+
end
78+
end
79+
80+
def ama_1_cent() do
81+
const = :persistent_term.get({ProtocolConstant, :ama_1_cent}, nil)
82+
if const do const else
83+
const = RDB.protocol_constants().ama_1_cent
84+
:persistent_term.put({ProtocolConstant, :ama_1_cent}, const)
85+
const
86+
end
87+
end
88+
89+
def forkheight() do
90+
const = :persistent_term.get({ProtocolConstant, :forkheight}, nil)
91+
if const do const else
92+
const = RDB.protocol_constants().forkheight
93+
:persistent_term.put({ProtocolConstant, :forkheight}, const)
94+
const
95+
end
96+
end
5797
end

ex/lib/node/txpool.ex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ defmodule TXPool do
5151

5252
def validate_tx(txu, args \\ %{}) do
5353
chain_epoch = Map.get_lazy(args, :epoch, fn()-> DB.Chain.epoch() end)
54+
chain_height = Map.get_lazy(args, :height, fn()-> DB.Chain.height() end)
5455
chain_segment_vr_hash = Map.get_lazy(args, :segment_vr_hash, fn()-> DB.Chain.segment_vr_hash() end)
5556
chain_diff_bits = Map.get_lazy(args, :diff_bits, fn()-> DB.Chain.diff_bits() end)
5657
batch_state = Map.get_lazy(args, :batch_state, fn()-> %{} end)
@@ -62,8 +63,13 @@ defmodule TXPool do
6263
batch_state = Map.put(batch_state, {:chain_nonce, txu.tx.signer}, txu.tx.nonce)
6364

6465
balance = Map.get_lazy(batch_state, {:balance, txu.tx.signer}, fn()-> DB.Chain.balance(txu.tx.signer) end)
65-
balance = balance - TX.exec_cost(chain_epoch, txu)
66-
balance = balance - BIC.Coin.to_cents(1)
66+
balance = if chain_height >= RDBProtocol.forkheight() do
67+
balance = balance - (RDBProtocol.reserve_ama_per_tx() * 2)
68+
balance = balance - TX.historical_cost(txu)
69+
else
70+
balance = balance - TX.exec_cost(chain_epoch, txu)
71+
balance = balance - BIC.Coin.to_cents(1)
72+
end
6773
if balance < 0, do: throw(%{error: :not_enough_tx_exec_balance, key: {txu.tx.nonce, txu.hash}})
6874
batch_state = Map.put(batch_state, {:balance, txu.tx.signer}, balance)
6975

@@ -84,6 +90,7 @@ defmodule TXPool do
8490
end
8591
end
8692

93+
#TODO: fix this, we dont need to validate VS chain here
8794
def event_tx_validate(txu) when is_map(txu) do event_tx_validate([txu]) end
8895
def event_tx_validate(txus) when is_list(txus) do
8996
chain_epoch = DB.Chain.epoch()

ex/native/rdb/src/atoms.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ rustler::atoms! {
5353
missing_stem_other_stem,
5454

5555
tx_cost,
56+
tx_historical_cost,
5657
tx_size,
5758

5859
direction,
@@ -64,4 +65,24 @@ rustler::atoms! {
6465
included,
6566
mismatch,
6667
nonexistance,
68+
69+
forkheight,
70+
71+
ama_1_dollar,
72+
ama_10_cent,
73+
ama_1_cent,
74+
75+
reserve_ama_per_tx,
76+
77+
cost_per_byte_historical,
78+
cost_per_byte_state,
79+
cost_per_op_wasm,
80+
81+
cost_per_db_read_base,
82+
cost_per_db_read_byte,
83+
cost_per_db_write_base,
84+
cost_per_db_write_byte,
85+
86+
cost_per_sol,
87+
cost_per_new_leaf_merkle,
6788
}

ex/native/rdb/src/consensus/bic/epoch.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,10 @@ pub fn call_slash_trainer(env: &mut crate::consensus::consensus_apply::ApplyEnv,
259259
let mask = args[4].to_vec();
260260

261261
if epoch != env.caller_env.entry_epoch { panic_any("invalid_epoch") }
262-
262+
println!("a{}", env.exec_left);
263263
let mut trainers = kv_get_trainers(env, env.caller_env.entry_height);
264264
if !trainers.iter().any(|v| v.as_slice() == malicious_pk) { panic_any("invalid_trainer_pk") }
265+
println!("b{}", env.exec_left);
265266

266267
let signers = consensus::aggsig::unmask_trainers(&trainers, &mask, mask_size as usize);
267268
let consensus_pct = signers.len() as f64 / trainers.len() as f64;
@@ -278,7 +279,12 @@ pub fn call_slash_trainer(env: &mut crate::consensus::consensus_apply::ApplyEnv,
278279
trainers.retain(|pk| pk.as_slice() != malicious_pk);
279280
let term_trainers = consensus::bic::list_of_binaries_to_vecpak(trainers);
280281
let height_next = format!("{:012}", env.caller_env.entry_height.saturating_add(1)).into_bytes();
282+
println!("c{}", env.exec_left);
283+
println!("zz{}", term_trainers.as_slice().len());
284+
281285
kv_put(env, &bcat(&[b"bic:epoch:validators:height:", &height_next]), term_trainers.as_slice());
286+
println!("d{}", env.exec_left);
287+
282288
}
283289

284290
pub fn next(env: &mut ApplyEnv) {

ex/native/rdb/src/consensus/bic/protocol.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
use crate::consensus::bic::coin;
22
use crate::consensus::consensus_kv;
33

4+
pub const FORKHEIGHT: u64 = 419_00000;
5+
//pub const FORKHEIGHT: u64 = 100;
6+
47
pub const AMA_1_DOLLAR: i128 = 1_000_000_000;
58
pub const AMA_10_CENT: i128 = 100_000_000;
69
pub const AMA_1_CENT: i128 = 10_000_000;
710

8-
pub const RESERVE_PER_TX_IN_ENTRY: i128 = AMA_10_CENT * 2; //minimum balance required per account per TX in a entry
11+
pub const RESERVE_AMA_PER_TX: i128 = AMA_10_CENT; //minimum balance required per account per TX in a entry
912

1013
pub const COST_PER_BYTE_HISTORICAL: i128 = 6_666; //cost to increase the ledger size
11-
pub const COST_PER_BYTE_STATE: i128 = 33_333; //cost to grow the contract state
14+
pub const COST_PER_BYTE_STATE: i128 = 16_666; //cost to grow the contract state
1215
pub const COST_PER_OP_WASM: i128 = 1; //cost to execute a wasm op
1316

14-
pub const COST_PER_DB_READ_BASE: i128 = 10_000;
15-
pub const COST_PER_DB_READ_BYTE: i128 = 100;
16-
pub const COST_PER_DB_WRITE_BASE: i128 = 50_000;
17-
pub const COST_PER_DB_WRITE_BYTE: i128 = 500;
17+
pub const COST_PER_DB_READ_BASE: i128 = 5_000;
18+
pub const COST_PER_DB_READ_BYTE: i128 = 50;
19+
pub const COST_PER_DB_WRITE_BASE: i128 = 25_000;
20+
pub const COST_PER_DB_WRITE_BYTE: i128 = 250;
1821

1922
pub const COST_PER_SOL: i128 = AMA_1_CENT; //cost to submit_sol
2023
pub const COST_PER_NEW_LEAF_MERKLE: i128 = COST_PER_BYTE_STATE * 128; //cost to grow the merkle tree

0 commit comments

Comments
 (0)