PascalCoin 5 years ago
parent
commit
8192ca9939
3 changed files with 74 additions and 6 deletions
  1. 7 1
      CHANGELOG.md
  2. 47 0
      PIP/PIP-0037.md
  3. 20 5
      src/core/UAccounts.pas

+ 7 - 1
CHANGELOG.md

@@ -12,8 +12,12 @@
 - Implementation of PIP-0027 (E-PASA Inifine Address-Space) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0027.md
   - Third party apps/implementations of hard coded operations need to pay attention of an extra byte added on each operation using Payload
   - TODO: Explain "in core" changes
+- Implementation of PIP-0037 (Distinguish account updates between active/passive mode)
+  - Added fields "updated_b_active_mode" and "updated_b_passive_mode" at each account to indicate in which block this account has been updated
+  - "active" means that private key has been used, so, is the initiator of the operation (can be as a sender or as a signer)
+  - "passive" means that this account is a receiver or a passive target (receiver or seller, for example)
 - Partial implementation of PIP-0012 (Recover Accounts option after 4 years) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0012.md
-  - Accounts updated counter will only update when executing operations in active mode (sender or signer)
+  - Accounts updated counter will only update when executing operations in active mode (See PIP-0037)
   - If account is a receiver (passive mode) then n_operation_update_block will not update value and can be recovered after 4 years (as defined on original PascalCoin v1 WhitePaper)
 - Fixed important security issue related to PIP-0003 caused by possible "parallelization" of the Proof-of-work
   - Discovered by Herman Schoenfeld <[email protected]>
@@ -53,6 +57,8 @@
     - "receiver_swap_account": (Integer) Counterpaty account that will receive "amount_to_swap" on ATOMIC COIN SWAP
     - "data" : (HEXASTRING) will return the Account Data stored with PIP-0024
     - "seal" : (HEXASTRING) will return the Account Seal stored with PIP-0029
+    - "updated_b_active_mode" : (Integer) Block number of last account change on active mode (private key usage for signature)
+    - "updated_b_passive_mode" : (Integer) Block number of last account change on passive mode (as a receiver of a transaction or similar)
   - Updated "Operation Object" return values:
     - "senders" : ARRAY
       - "payload_type" : (Byte) as described on PIP-0027

+ 47 - 0
PIP/PIP-0037.md

@@ -0,0 +1,47 @@
+<pre>
+  PIP: PIP-0037
+  Title: Distinguish account updates between active/passive mode
+  Type: Protocol
+  Impact: Hard-Fork
+  Author: Albert Molina based on @bentley idea at Discord Channel and others
+  Comments-URI: https://discord.gg/sJqcgtD
+  Status: Proposed
+  Created: 2019-10-20
+</pre>
+
+## Summary
+
+Update the previous `Account.updated_block` field to distinguish between **active** updates versus **passive** updates
+
+## Motivation
+
+Motivated by the activation of the PIP-0012 and some improvements made that distinguish between an active usage of the account versus a passive modification
+
+## Background 
+
+Currently the OP_RECOVER operation is based on a single `updated_block` field that is updated each time an account changes.
+
+The change can be caused by any operation that affects this account, even if the private key of this account has not been used (for example, receiving a transaction)
+
+In order to distinguish when the update has been made in active or passive mode, the proposal is to separate the single `update_block` field in 2 fields:
+- `updated_on_block_active_mode`
+- `updated_on_block_passive_mode`
+
+Adding this distinction, will allow a fair use of the OP_RECOVER operation as was originally designed in initial PascalCoin WhitePaper
+
+## Specification
+
+Add 2 new fields on `Account` object:
+- `updated_on_block_active_mode`
+- `updated_on_block_passive_mode`
+
+Delete the previous `updated_block` field because can be calculated with `=MAX( updated_on_block_active_mode, updated_on_block_passive_mode)`
+
+Definition of **active mode**
+
+When an account is the originator of the operation and the private key of this account has been used.
+
+For example: A `Sender` of any transaction, or when an account has been changed it's state including when is not the signer of the operation
+
+By definition, every time `n_operation` field is updated, `updated_on_block_active_mode` is updated too
+

+ 20 - 5
src/core/UAccounts.pas

@@ -1270,6 +1270,7 @@ class procedure TAccountComp.SaveAccountToAStream(Stream: TStream; const Account
 var w : Word;
   LTmpSeal : T20Bytes;
   LTmpRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
   if current_protocol<CT_PROTOCOL_5 then
     w := CT_PROTOCOL_4
@@ -1278,9 +1279,12 @@ begin
   Stream.Write(Account.account,Sizeof(Account.account));
   TStreamOp.WriteAnsiString(Stream,AccountInfo2RawString(Account.accountInfo));
   Stream.Write(Account.balance,Sizeof(Account.balance));
-  Stream.Write(Account.updated_on_block_passive_mode,Sizeof(Account.updated_on_block_passive_mode));
   if current_protocol>=CT_PROTOCOL_5 then begin
+    Stream.Write(Account.updated_on_block_passive_mode,Sizeof(Account.updated_on_block_passive_mode));
     Stream.Write(Account.updated_on_block_active_mode,Sizeof(Account.updated_on_block_active_mode));
+  end else begin
+    LCardinal := Account.GetLastUpdatedBlock;
+    Stream.Write(LCardinal,Sizeof(LCardinal));
   end;
   Stream.Write(Account.n_operation,Sizeof(Account.n_operation));
   TStreamOp.WriteAnsiString(Stream,Account.name);
@@ -2252,6 +2256,7 @@ var i, base_addr : Integer;
   //
   account_dev,
   account_0 : TAccount;
+  LAccountKey: TAccountKey;
   //
   acc_0_miner_reward,acc_4_dev_reward : Int64;
   acc_4_for_dev : Boolean;
@@ -2268,6 +2273,11 @@ begin
     If (AccountsCount>account_0.account_type) then begin
       account_dev := Account(account_0.account_type);
     end else account_dev := account_0;
+    if (account_dev.account=0) then begin
+      LAccountKey := blockChain.account_key;
+    end else begin
+      LAccountKey := account_dev.accountInfo.accountKey;
+    end;
   end;
 
   base_addr := BlocksCount * CT_AccountsPerBlock;
@@ -2281,7 +2291,7 @@ begin
     Result.accounts[i].updated_on_block_active_mode := BlocksCount;
     Result.accounts[i].n_operation := 0;
     if (acc_4_for_dev) And (i=CT_AccountsPerBlock-1) then begin
-      Result.accounts[i].accountInfo.accountKey := account_dev.accountInfo.accountKey;
+      Result.accounts[i].accountInfo.accountKey := LAccountKey;
       SetLength(accs_dev,length(accs_dev)+1);
       accs_dev[High(accs_dev)] := base_addr + i;
       Result.accounts[i].balance := acc_4_dev_reward;
@@ -2314,7 +2324,7 @@ begin
     AccountKeyListAddAccounts(blockChain.account_key,accs_miner);
   end;
   If (length(accs_dev)>0) then begin
-    AccountKeyListAddAccounts(account_dev.accountInfo.accountKey,accs_dev);
+    AccountKeyListAddAccounts(LAccountKey,accs_dev);
   end;
   // Calculating new value of safebox
   FSafeBoxHash := CalcSafeBoxHash;
@@ -3546,9 +3556,12 @@ begin
       Stream.Write(b.accounts[iacc].account,Sizeof(b.accounts[iacc].account));
       TStreamOp.WriteAnsiString(Stream,TAccountComp.AccountInfo2RawString(b.accounts[iacc].accountInfo));
       Stream.Write(b.accounts[iacc].balance,Sizeof(b.accounts[iacc].balance));
-      Stream.Write(b.accounts[iacc].updated_on_block_passive_mode,Sizeof(b.accounts[iacc].updated_on_block_passive_mode));
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
+        Stream.Write(b.accounts[iacc].updated_on_block_passive_mode,Sizeof(b.accounts[iacc].updated_on_block_passive_mode));
         Stream.Write(b.accounts[iacc].updated_on_block_active_mode,Sizeof(b.accounts[iacc].updated_on_block_active_mode));
+      end else begin
+        LCardinal := b.accounts[iacc].GetLastUpdatedBlock;
+        Stream.Write(LCardinal,SizeOf(LCardinal));
       end;
       Stream.Write(b.accounts[iacc].n_operation,Sizeof(b.accounts[iacc].n_operation));
       If FCurrentProtocol>=CT_PROTOCOL_2 then begin
@@ -5929,6 +5942,7 @@ end;
 
 procedure TAccount_Helper.SerializeAccount(AStream: TStream; current_protocol : Word);
 var LRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
   if current_protocol>=CT_PROTOCOL_5 then TAccountComp.SaveAccountToAStream(AStream,Self,current_protocol)
   else begin
@@ -5936,7 +5950,8 @@ begin
     LRaw := TAccountComp.AccountInfo2RawString(Self.accountInfo);
     AStream.WriteBuffer(LRaw[Low(LRaw)],Length(LRaw));
     AStream.Write(Self.balance,8);
-    AStream.Write(Self.updated_on_block_passive_mode,4);
+    LCardinal := Self.GetLastUpdatedBlock;
+    AStream.Write(LCardinal,4);
     AStream.Write(Self.n_operation,4);
     if (current_protocol>=2) then begin
         // Use new Protocol 2 fields