Browse Source

Use TAccount.accountInfo.hashed_secret to store HASHED SECRET for Atomic Swaps instead of Account.Data

This will give freedom to use TAccount.Data for general purposes and will not be forced new value by Atomic Swaps
PascalCoin 6 years ago
parent
commit
5886c86659

+ 17 - 6
src/core/UAccounts.pas

@@ -44,6 +44,7 @@ Type
     price : UInt64;                // 0 = invalid price
     account_to_pay : Cardinal;     // <> itself
     new_publicKey : TAccountKey;
+    hashed_secret : TRawBytes;     // Hashed Secret for AtomicSwaps
   end;
 
   TOperationBlock = Record
@@ -138,7 +139,7 @@ Type
     Class function IsNullAccountKey(const AAccountInfo : TAccountKey) : Boolean;
     Class function IsValidNewAccountKey(const AAccountInfo : TAccountInfo; const ANewKey : TAccountKey; AProtocolVersion : Integer) : Boolean;
     Class Function IsValidAccountInfo(const AAccountInfo: TAccountInfo; var errors : String): Boolean;
-    Class Function IsValidAccountHashLockKey(const AAccount : TAccount; const AKey : TRawBytes) : Boolean;
+    Class Function IsValidAccountInfoHashLockKey(const AAccountInfo : TAccountInfo; const AKey : TRawBytes) : Boolean;
     Class Function IsValidHashLockKey(const AKey : TRawBytes; out AError : String) : Boolean;
     Class Function CalculateHashLock(const AKey : TRawBytes) : T32Bytes;
     Class Function IsAccountForSale(const AAccountInfo: TAccountInfo) : Boolean;
@@ -507,7 +508,7 @@ Type
 Const
   CT_OperationBlock_NUL : TOperationBlock = (block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
     protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil);
-  CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));
+  CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);hashed_secret:Nil);
   CT_Account_NUL : TAccount = (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0);
   CT_BlockAccount_NUL : TBlockAccount = (
     blockchainInfo:(block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
@@ -1156,6 +1157,10 @@ begin
         ms.Write(AccountInfo.price,SizeOf(AccountInfo.price));
         ms.Write(AccountInfo.account_to_pay,SizeOf(AccountInfo.account_to_pay));
         TStreamOp.WriteAccountKey(ms,AccountInfo.new_publicKey);
+        // Adding Hashed_secret if Atomic Swap
+        if AccountInfo.state in [as_ForAtomicAccountSwap,as_ForAtomicCoinSwap] then begin
+          TStreamOp.WriteAnsiString(ms,AccountInfo.hashed_secret);
+        end;
         SetLength(dest,ms.Size);
         ms.Position := 0;
         ms.Read(dest[Low(dest)],ms.Size);
@@ -1457,9 +1462,9 @@ begin
   end;
 end;
 
-Class Function TAccountComp.IsValidAccountHashLockKey(const AAccount : TAccount; const AKey : TRawBytes) : Boolean;
+Class Function TAccountComp.IsValidAccountInfoHashLockKey(const AAccountInfo : TAccountInfo; const AKey : TRawBytes) : Boolean;
 begin
-  Result := BytesEqual( TBaseType.ToRawBytes( CalculateHashLock( AKey ) ), AAccount.account_data);
+  Result := BytesEqual( TBaseType.ToRawBytes( CalculateHashLock( AKey ) ), AAccountInfo.hashed_secret);
 end;
 
 Class Function TAccountComp.IsValidHashLockKey(const AKey : TRawBytes; out AError : String) : Boolean;
@@ -1528,7 +1533,7 @@ begin
       exit;
 
    if (AAccount.accountInfo.state in [as_ForAtomicAccountSwap, as_ForAtomicCoinSwap]) then
-     if NOT IsValidAccountHashLockKey(AAccount, APayload) then
+     if NOT IsValidAccountInfoHashLockKey(AAccount.accountInfo, APayload) then
        exit;
   Result := True;
 end;
@@ -1708,6 +1713,7 @@ begin
         dest.price:=CT_AccountInfo_NUL.price;
         dest.account_to_pay:=CT_AccountInfo_NUL.account_to_pay;
         dest.new_publicKey:=CT_AccountInfo_NUL.new_publicKey;
+        dest.hashed_secret:=CT_AccountInfo_NUL.hashed_secret;
       End;
       CT_AccountInfo_ForSale, CT_AccountInfo_ForAccountSwap, CT_AccountInfo_ForCoinSwap : Begin
         TStreamOp.ReadAccountKey(ms,dest.accountKey);
@@ -1720,6 +1726,11 @@ begin
           CT_AccountInfo_ForAccountSwap: dest.state := as_ForAtomicAccountSwap;
           CT_AccountInfo_ForCoinSwap: dest.state := as_ForAtomicCoinSwap;
         end;
+        if dest.state in [as_ForAtomicAccountSwap,as_ForAtomicCoinSwap] then begin
+          TStreamOp.ReadAnsiString(ms,dest.hashed_secret);
+        end else begin
+          dest.hashed_secret:=CT_AccountInfo_NUL.hashed_secret;
+        end;
       End;
     else
       raise Exception.Create('DEVELOP ERROR 20170214-2');
@@ -4189,7 +4200,7 @@ begin
       TAccountComp.FormatMoney(LPAccountToBuy^.balance)+' + amount '+TAccountComp.FormatMoney(AAmount);
     Exit;
   end;
-  if TAccountComp.IsAccountForSwap(LPAccountToBuy^.accountInfo) AND (NOT TAccountComp.IsValidAccountHashLockKey(LPAccountToBuy^, AHashLockKey)) then begin
+  if TAccountComp.IsAccountForSwap(LPAccountToBuy^.accountInfo) AND (NOT TAccountComp.IsValidAccountInfoHashLockKey(LPAccountToBuy^.accountInfo, AHashLockKey)) then begin
     AErrors := 'Account is not unlocked by supplied hash lock key';
     Exit;
   end;

+ 4 - 1
src/core/UBlockChain.pas

@@ -149,6 +149,7 @@ Type
     Seller_Account : Int64;
     Account_Price : Int64;
     Locked_Until_Block : Cardinal;
+    Hashed_secret : TRawBytes;
     Data : TMultiOpData;
     Fee: Int64;
     Signature: TECDSA_SIG;
@@ -560,7 +561,9 @@ Const
   CT_TOperationResume_NUL : TOperationResume = (valid:false;Block:0;NOpInsideBlock:-1;OpType:0;OpSubtype:0;time:0;AffectedAccount:0;SignerAccount:-1;n_operation:0;DestAccount:-1;SellerAccount:-1;newKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);OperationTxt:'';Amount:0;Fee:0;Balance:0;OriginalPayload:Nil;PrintablePayload:'';OperationHash:Nil;OperationHash_OLD:Nil;errors:'';isMultiOperation:False;Senders:Nil;Receivers:Nil;changers:Nil);
   CT_TMultiOpSender_NUL : TMultiOpSender =  (Account:0;Amount:0;N_Operation:0;Payload:Nil;Signature:(r:Nil;s:Nil));
   CT_TMultiOpReceiver_NUL : TMultiOpReceiver = (Account:0;Amount:0;Payload:Nil);
-  CT_TMultiOpChangeInfo_NUL : TMultiOpChangeInfo = (Account:0;N_Operation:0;Changes_type:[];New_Accountkey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);New_Name:Nil;New_Type:0;Seller_Account:-1;Account_Price:-1;Locked_Until_Block:0;Fee:0;Signature:(r:Nil;s:Nil));
+  CT_TMultiOpChangeInfo_NUL : TMultiOpChangeInfo = (Account:0;N_Operation:0;Changes_type:[];New_Accountkey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);New_Name:Nil;New_Type:0;Seller_Account:-1;Account_Price:-1;Locked_Until_Block:0;
+    Hashed_secret:Nil;
+    Fee:0;Signature:(r:Nil;s:Nil));
   CT_TOpChangeAccountInfoType_Txt : Array[Low(TOpChangeAccountInfoType)..High(TOpChangeAccountInfoType)] of String = ('public_key','account_name','account_type','list_for_public_sale','list_for_private_sale', 'delist', 'account_data','list_for_account_swap','list_for_coin_swap');
 
 implementation

+ 11 - 6
src/core/UOpTransaction.pas

@@ -2007,14 +2007,19 @@ begin
     account_target.accountInfo.price := CT_AccountInfo_NUL.price;
     account_target.accountInfo.account_to_pay := CT_AccountInfo_NUL.account_to_pay;
     account_target.accountInfo.new_publicKey := CT_AccountInfo_NUL.new_publicKey;
+    account_target.accountInfo.hashed_secret := CT_AccountInfo_NUL.hashed_secret;
   end else begin
     account_target.accountInfo.state := FData.account_state;
     account_target.accountInfo.locked_until_block := FData.locked_until_block;
     account_target.accountInfo.price := FData.account_price;
     account_target.accountInfo.account_to_pay := FData.account_to_pay;
     account_target.accountInfo.new_publicKey := FData.new_public_key;
-    if LIsSwap then
-      account_target.account_data := TBaseType.ToRawBytes( FData.hash_lock );
+    if LIsSwap then begin
+      account_target.accountInfo.hashed_secret := TBaseType.ToRawBytes( FData.hash_lock );
+    end else begin
+      // FData.hash_lock has no utility when no AtomicSwap
+      account_target.accountInfo.hashed_secret := CT_AccountInfo_NUL.hashed_secret;
+    end;
   end;
 
   Result := AccountTransaction.UpdateAccountInfo(
@@ -2105,13 +2110,13 @@ begin
   OperationResume.Changers[0].Account:=FData.account_target;
   case FData.operation_type of
     lat_ListAccount : begin
-        if (FData.new_public_key.EC_OpenSSL_NID=CT_TECDSA_Public_Nul.EC_OpenSSL_NID) then begin
+        if (FData.account_state = as_ForSale) And (FData.new_public_key.EC_OpenSSL_NID=CT_TECDSA_Public_Nul.EC_OpenSSL_NID) then begin
           OperationResume.Changers[0].Changes_type:=[list_for_public_sale];
         end else begin
           if FData.account_state = as_ForAtomicAccountSwap then
-            OperationResume.Changers[0].Changes_type:=[list_for_account_swap, account_data]
+            OperationResume.Changers[0].Changes_type:=[list_for_account_swap]
           else if FData.account_state = as_ForAtomicCoinSwap then
-            OperationResume.Changers[0].Changes_type:=[list_for_coin_swap, account_data]
+            OperationResume.Changers[0].Changes_type:=[list_for_coin_swap]
           else
             OperationResume.Changers[0].Changes_type:=[list_for_private_sale];
           OperationResume.Changers[0].New_Accountkey := FData.new_public_key;
@@ -2120,7 +2125,7 @@ begin
         OperationResume.Changers[0].Seller_Account:=FData.account_to_pay;
         OperationResume.Changers[0].Account_Price:=FData.account_price;
         if (FData.account_state in [as_ForAtomicAccountSwap, as_ForAtomicCoinSwap]) then begin
-          OperationResume.Changers[0].New_Data := TBaseType.ToRawBytes( FData.hash_lock );
+          OperationResume.Changers[0].Hashed_secret := TBaseType.ToRawBytes( FData.hash_lock );
         end;
     end;
     lat_DelistAccount : begin

+ 13 - 6
src/core/URPC.pas

@@ -257,14 +257,21 @@ Begin
         auxObj.GetAsVariant('new_data').Value := OPR.Changers[i].New_Data.ToHexaString;
       end;
       if (list_for_public_sale in OPR.Changers[i].Changes_type)
-        Or (list_for_private_sale in OPR.Changers[i].Changes_type) then begin
+         or (list_for_private_sale in OPR.Changers[i].Changes_type)
+         or (list_for_account_swap in OPR.Changers[i].Changes_type)
+         or (list_for_coin_swap in OPR.Changers[i].Changes_type) then begin
         auxObj.GetAsVariant('seller_account').Value := OPR.Changers[i].Seller_Account;
         auxObj.GetAsVariant('account_price').Value := TAccountComp.FormatMoneyDecimal(OPR.Changers[i].Account_Price);
         auxObj.GetAsVariant('account_price_s').Value := TAccountComp.FormatMoney(OPR.Changers[i].Account_Price);
-      end;
-      if (list_for_private_sale in OPR.Changers[i].Changes_type) then begin
         auxObj.GetAsVariant('locked_until_block').Value := OPR.Changers[i].Locked_Until_Block;
-        auxObj.GetAsVariant('new_enc_pubkey').Value := TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(OPR.Changers[i].New_Accountkey));
+        if (list_for_private_sale in OPR.Changers[i].Changes_type)
+          or (list_for_account_swap in OPR.Changers[i].Changes_type) then begin
+          auxObj.GetAsVariant('new_enc_pubkey').Value := TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(OPR.Changers[i].New_Accountkey));
+        end;
+        if (list_for_account_swap in OPR.Changers[i].Changes_type)
+          or (list_for_coin_swap in OPR.Changers[i].Changes_type) then begin
+          auxObj.GetAsVariant('hashed_secret').Value := OPR.Changers[i].Hashed_secret.ToHexaString;
+        end;
       end;
       if (OPR.Changers[i].Fee<>0) then begin
         auxObj.GetAsVariant('fee').Value := TAccountComp.FormatMoneyDecimal(OPR.Changers[i].Fee * (-1));
@@ -337,7 +344,7 @@ Begin
       jsonObj.GetAsVariant('state').Value:='account_swap';
       jsonObj.GetAsVariant('locked_until_block').Value:=account.accountInfo.locked_until_block;
       jsonObj.GetAsVariant('new_enc_pubkey').Value := TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(account.accountInfo.new_publicKey));
-      jsonObj.GetAsVariant('hashed_secret').Value := account.account_data.ToHexaString;
+      jsonObj.GetAsVariant('hashed_secret').Value := account.accountInfo.hashed_secret.ToHexaString;
     end;
     as_ForAtomicCoinSwap : begin
       jsonObj.GetAsVariant('state').Value:='coin_swap';
@@ -345,7 +352,7 @@ Begin
       jsonObj.GetAsVariant('amount_to_swap').Value:=TAccountComp.FormatMoneyDecimal(account.accountInfo.price);
       jsonObj.GetAsVariant('amount_to_swap_s').Value:=TAccountComp.FormatMoney(account.accountInfo.price);
       jsonObj.GetAsVariant('receiver_swap_account').Value:=account.accountInfo.account_to_pay;
-      jsonObj.GetAsVariant('hashed_secret').Value := account.account_data.ToHexaString;
+      jsonObj.GetAsVariant('hashed_secret').Value := account.accountInfo.hashed_secret.ToHexaString;
     end;
   else raise Exception.Create('ERROR DEV 20170425-1');
   end;

+ 1 - 0
src/core/UTxMultiOperation.pas

@@ -705,6 +705,7 @@ begin
       changer.accountInfo.price := 0;
       changer.accountInfo.account_to_pay := 0;
       changer.accountInfo.new_publicKey := CT_TECDSA_Public_Nul;
+      changer.accountInfo.hashed_secret := Nil;
     end;
     If (account_name in chi.Changes_type) then begin
       changer.name := chi.New_Name;

+ 1 - 1
src/gui-classic/UFRMWallet.pas

@@ -931,7 +931,7 @@ begin
       Strings.Add(Format('Amount to swap: %s',[TAccountComp.FormatMoney(account.accountInfo.price)]));
       Strings.Add(Format('Counterparty account: %s',[TAccountComp.AccountNumberToAccountTxtNumber(account.accountInfo.account_to_pay)]));
     end;
-    Strings.Add(Format('Public secret to find: %s',[account.account_data.ToHexaString]));
+    Strings.Add(Format('Public secret to find: %s',[account.accountInfo.hashed_secret.ToHexaString]));
     Strings.Add('');
     if TAccountComp.IsAccountLocked(account.accountInfo,FNode.Bank.BlocksCount) then begin
       Strings.Add(Format('SWAP IS SECURE UNTIL BLOCK %d (current %d, remains %d)',