-
Notifications
You must be signed in to change notification settings - Fork 38
[GH-#125] Add lock time to transaction #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…tored code and tests
apps/aecore/config/dev.exs
Outdated
| peers_max_count: 4 | ||
|
|
||
| config :aecore, :tx_data, | ||
| lock_time_block: 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name it lock_time_coinbase
|
|
||
| update_block_state(updated_block_state, transaction.data.to_acc, transaction.data.value, 0) | ||
| add_to_amount = latest_block_height + 1 != | ||
| transaction.data.lock_time_block - Application.get_env(:aecore, :tx_data)[:lock_time_block] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't get the env here, pass it to the function
| chain_state |> | ||
| Enum.map(fn{_account, data} -> data.balance end) |> | ||
| Enum.sum() | ||
| chain_state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe return a tuple of {total_tokens, total_unlocked_tokens, total_locked_tokens}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add a test to check if locked token can't actually be spent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally good, but please address mine and thepiwo comments.
| {amount_update_value + amount, updated_locked} | ||
|
|
||
| true -> | ||
| {amount_update_value, updated_locked} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't happen. Let's log an error here.
| @spec update_chain_state_locked(map(), integer()) :: map() | ||
| def update_chain_state_locked(chain_state, new_block_height) do | ||
| Enum.reduce(chain_state, %{}, fn({account, %{balance: balance, nonce: nonce, locked: locked}}, acc) -> | ||
| {locked_amount, updated_locked} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call locked_amount: unlocked_amount or just_unlocked_amount or to_unlock_amount to be less confusing.
|
|
||
| new_account_state = %{balance: block_state_filled_empty[account].balance + value, | ||
| nonce: new_nonce} | ||
| new_locked = if(value > 0) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If add_to_amount is true we add value to account twice (we duplicate tokens!). One's on current block and again on lock_time_block!
What we should do instead is check add_to_amount and do one of two things: add to balance or add to locked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so if value < 0 then add_to_amount should be always true. If add_to_amount is false then the call is a no-op and we should produce an error to logs or maybe raise some exception or assert? @thepiwo What should we do if there in such a case (what is "the-best-practise")?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we should raise an exception, but why handle the case at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cheezus1 here is the answer
| ChainState.calculate_block_state(block.txs) | ||
| assert %{"a" => %{balance: -9, nonce: 102, | ||
| locked: [%{amount: 10, block: lock_time_block}]}, | ||
| "b" => %{nonce: 1, balance: -11, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that's the same as before, but why do we actually get negative balances?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoops, good question
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because amounts are spent this block, but the received amounts for each are locked for one block? Correct me if I am wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cytadela8 this is just the block_state indicating the change this block makes to the chain_state, negative values occur for every token spent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, right. This is not the chain_state after the block. It's delta chain_state.
|
@cheezus1 is there a test to check if locked token can't actually be spent? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last issue.
|
|
||
| new_account_state = %{balance: block_state_filled_empty[account].balance + value, | ||
| nonce: new_nonce} | ||
| new_locked = if(value > 0) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so if value < 0 then add_to_amount should be always true. If add_to_amount is false then the call is a no-op and we should produce an error to logs or maybe raise some exception or assert? @thepiwo What should we do if there in such a case (what is "the-best-practise")?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good now. Great work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question + can we add a test to check if locked coins can't be spend and after locktime they can?
| Map.get(Chain.chain_state, account1_pub_key, %{nonce: 0}).nonce + 1, 1) | ||
| Map.get(Chain.chain_state, account1_pub_key, %{nonce: 0}).nonce + 1, 1, | ||
| Chain.latest_block().header.height + | ||
| Application.get_env(:aecore, :tx_data)[:lock_time_coinbase] + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we add locktime to all of the transactions in tests?
| @spec sign_tx(binary(), integer(), integer(), integer(), integer()) :: {:ok, %SignedTx{}} | ||
| def sign_tx(to_acc, value, nonce, fee, lock_time_block) do | ||
| def sign_tx(to_acc, value, nonce, fee, | ||
| lock_time_block \\ Chain.latest_block().header.height + 1) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you want to lock a transaction by default? I would set the default to 0
…orks in all cases; added test for checking if locked amount is spendable
|
@cheezus1 We still have merge conflicts |
closes #125, #138