Browse Source

More bugs

PascalCoin 7 years ago
parent
commit
271775c954
4 changed files with 61 additions and 19 deletions
  1. 43 7
      src/core/UAccounts.pas
  2. 3 0
      src/core/UBlockChain.pas
  3. 1 1
      src/core/UNetProtocol.pas
  4. 14 11
      src/core/UTxMultiOperation.pas

+ 43 - 7
src/core/UAccounts.pas

@@ -355,6 +355,7 @@ Type
     procedure CheckMemory;
     Property PreviousSafeboxOriginBlock : Integer Read FPreviousSafeboxOriginBlock;
     Function GetMinimumAvailableSnapshotBlock : Integer;
+    Function HasSnapshotForBlock(block_number : Cardinal) : Boolean;
   End;
 
 
@@ -1950,17 +1951,31 @@ procedure TPCSafeBox.CheckMemory;
 {$IFDEF FPC}
 Var sb : TPCSafeBox;
   tc : TTickCount;
+  auxSnapshotsList : TList;
 {$ENDIF}
 begin
   {$IFDEF FPC}
   StartThreadSafe;
   try
+    If Assigned(FPreviousSafeBox) then Exit; // When loading from snapshot, does not allow to check memory!
     tc := TPlatform.GetTickCount;
     sb := TPCSafeBox.Create;
     try
-      sb.CopyFrom(Self);
-      Self.Clear;
-      Self.CopyFrom(sb);
+      //
+      auxSnapshotsList := TList.Create;
+      Try
+        // Save snapshots:
+        auxSnapshotsList.Assign(FSnapshots);
+        FSnapshots.Clear;
+        //
+        sb.CopyFrom(Self);
+        Self.Clear;
+        Self.CopyFrom(sb);
+        // Restore snapshots:
+        FSnapshots.Assign(auxSnapshotsList);
+      finally
+        auxSnapshotsList.Free;
+      end;
     finally
       sb.Free;
     end;
@@ -1973,7 +1988,6 @@ end;
 
 function TPCSafeBox.GetMinimumAvailableSnapshotBlock: Integer;
 Var Pss : PSafeboxSnapshot;
-  i : Integer;
 begin
   Result := -1;
   StartThreadSafe;
@@ -1987,6 +2001,21 @@ begin
   end;
 end;
 
+function TPCSafeBox.HasSnapshotForBlock(block_number: Cardinal): Boolean;
+Var Pss : PSafeboxSnapshot;
+  i : Integer;
+begin
+  Result := False;
+  StartThreadSafe;
+  Try
+    i := FSnapshots.Count-1;
+    while (i>=0) And (PSafeboxSnapshot( FSnapshots[i] )^.nBlockNumber<>block_number) do dec(i);
+    Result := (i>=0);
+  finally
+    EndThreadSave;
+  end;
+end;
+
 procedure TPCSafeBox.Clear;
 Var i : Integer;
   P : PBlockAccount;
@@ -2498,6 +2527,7 @@ begin
       case sbHeader.protocol of
         CT_PROTOCOL_1 : FCurrentProtocol := 1;
         CT_PROTOCOL_2 : FCurrentProtocol := 2;
+        CT_PROTOCOL_3 : FCurrentProtocol := 3;
       else exit;
       end;
       if (sbHeader.blocksCount=0) Or (sbHeader.startBlock<>0) Or (sbHeader.endBlock<>(sbHeader.blocksCount-1)) then begin
@@ -2656,7 +2686,7 @@ begin
     if (s<>CT_MagicIdentificator) then exit;
     if Stream.Size<8 then exit;
     Stream.Read(w,SizeOf(w));
-    if not (w in [1,2]) then exit;
+    if not (w in [CT_PROTOCOL_1,CT_PROTOCOL_2,CT_PROTOCOL_3]) then exit;
     sbHeader.protocol := w;
     Stream.Read(safeBoxBankVersion,2);
     if safeBoxBankVersion<>CT_SafeBoxBankVersion then exit;
@@ -3377,7 +3407,7 @@ begin
       If blockAccount.accounts[iAccount].name<>'' then begin
         i := FOrderedByName.IndexOf(blockAccount.accounts[iAccount].name);
         if i>=0 then TLog.NewLog(ltError,ClassName,'ERROR DEV 20170606-2 New Name "'+blockAccount.accounts[iAccount].name+'" for account '+IntToStr(account_number)+' found at account '+IntToStr(FOrderedByName.GetTag(i)));
-        FOrderedByName.Add(blockAccount.accounts[iAccount].name,account_number); // XXXXXXXXXX BUG! Must add!
+        FOrderedByName.Add(blockAccount.accounts[iAccount].name,account_number);
 
         iDeleted := FDeletedNamesSincePreviousSafebox.IndexOf(blockAccount.accounts[iAccount].name);
         iAdded := FAddedNamesSincePreviousSafebox.IndexOf(blockAccount.accounts[iAccount].name);
@@ -3818,7 +3848,7 @@ function TPCSafeBoxTransaction.TransferAmounts(previous : TAccountPreviousBlockI
   n_operations: array of Cardinal; const sender_amounts: array of UInt64;
   const receivers: array of Cardinal; const receivers_amounts: array of UInt64;
   var errors: AnsiString): Boolean;
-Var i : Integer;
+Var i,j : Integer;
   PaccSender, PaccTarget : PAccount;
   nTotalAmountSent, nTotalAmountReceived, nTotalFee : Int64;
 begin
@@ -3844,6 +3874,12 @@ begin
   end;
   // Check sender
   for i:=Low(senders) to High(senders) do begin
+    for j:=i+1 to High(senders) do begin
+      if (senders[i]=senders[j]) then begin
+        errors := 'Duplicated sender';
+        Exit;
+      end;
+    end;
     if (senders[i]<0) Or (senders[i]>=(Origin_BlocksCount*CT_AccountsPerBlock)) then begin
        errors := 'Invalid sender on transfer';
        exit;

+ 3 - 0
src/core/UBlockChain.pas

@@ -650,6 +650,8 @@ begin
         if Not Storage.LoadBlockChainBlock(FLastBlockCache,BlocksCount-1) then begin
           NewLog(nil,lterror,'Cannot find blockchain '+inttostr(BlocksCount-1)+' so cannot accept bank current block '+inttostr(BlocksCount));
           Clear;
+        end else begin
+          FLastOperationBlock := FLastBlockCache.OperationBlock;
         end;
       end;
       NewLog(Nil, ltinfo,'Start restoring from disk operations (Max '+inttostr(max_block)+') BlockCount: '+inttostr(BlocksCount)+' Orphan: ' +Storage.Orphan);
@@ -2574,6 +2576,7 @@ begin
       OperationResume.isMultiOperation:=True;
       OperationResume.OpSubtype := CT_OpSubtype_MultiOperation;
       OperationResume.OperationTxt := Operation.ToString;
+      Result := True;
     end
   else Exit;
   end;

+ 1 - 1
src/core/UNetProtocol.pas

@@ -1547,7 +1547,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       Bank.Storage.ReadOnly := true;
       Bank.Storage.CopyConfiguration(TNode.Node.Bank.Storage);
       if start_block>=0 then begin
-        If (TNode.Node.Bank.SafeBox.GetMinimumAvailableSnapshotBlock<start_block) then begin
+        If (TNode.Node.Bank.SafeBox.HasSnapshotForBlock(start_block-1)) then begin
           // XXXXXXXXXXXXX
           // XXXXXXXXXXXXX
           // Restore from a Snapshot (New on V3) instead of restore reading from File

+ 14 - 11
src/core/UTxMultiOperation.pas

@@ -133,12 +133,13 @@ Type
     Function AddChangeInfo(const changes : TMultiOpChangesInfo; setInRandomOrder : Boolean) : Boolean;
     //
     Function IndexOfAccountSender(nAccount : Cardinal) : Integer; overload;
-    Function IndexOfAccountSender(nAccount : Cardinal; startPos : Integer; const txSenders : TMultiOpSenders) : Integer; overload;
+    class Function IndexOfAccountSender(nAccount : Cardinal; startPos : Integer; const txSenders : TMultiOpSenders) : Integer; overload;
     Function IndexOfAccountReceiver(nAccount : Cardinal; startPos : Integer) : Integer;
     Function IndexOfAccountChanger(nAccount : Cardinal) : Integer; overload;
-    Function IndexOfAccountChanger(nAccount : Cardinal; startPos : Integer; const changesInfo : TMultiOpChangesInfo) : Integer; overload;
+    class Function IndexOfAccountChanger(nAccount : Cardinal; startPos : Integer; const changesInfo : TMultiOpChangesInfo) : Integer; overload;
     //
     Function toString : String; Override;
+    Property Data : TOpMultiOperationData read FData;
   End;
 
 
@@ -153,7 +154,7 @@ begin
   Result := IndexOfAccountSender(nAccount,0,FData.txSenders);
 end;
 
-function TOpMultiOperation.IndexOfAccountSender(nAccount: Cardinal; startPos : Integer; const txSenders: TMultiOpSenders): Integer;
+class function TOpMultiOperation.IndexOfAccountSender(nAccount: Cardinal; startPos : Integer; const txSenders: TMultiOpSenders): Integer;
 begin
   for Result:=startPos to high(txSenders) do begin
     If (txSenders[Result].Account = nAccount) then exit;
@@ -175,7 +176,7 @@ begin
   Result := IndexOfAccountChanger(nAccount,0,FData.changesInfo);
 end;
 
-function TOpMultiOperation.IndexOfAccountChanger(nAccount: Cardinal; startPos : Integer; const changesInfo: TMultiOpChangesInfo): Integer;
+class function TOpMultiOperation.IndexOfAccountChanger(nAccount: Cardinal; startPos : Integer; const changesInfo: TMultiOpChangesInfo): Integer;
 begin
   for Result:=startPos to high(changesInfo) do begin
     If (changesInfo[Result].Account = nAccount) then exit;
@@ -356,7 +357,7 @@ begin
       end;
     end;
     Result := AddTx(txsenders,txreceivers,False); // Important: Set in same order!
-    Result := Result or AddChangeInfo(changes,False); // Important: Set in same order!
+    Result := Result And AddChangeInfo(changes,False); // Important: Set in same order!
   Except
     On E:Exception do begin
       TLog.NewLog(lterror,Self.ClassName,'('+E.ClassName+'):'+E.Message);
@@ -372,7 +373,7 @@ begin
   old := FSaveSignatureValue;
   try
     FSaveSignatureValue := False;
-    Result:=inherited GetBufferForOpHash(UseProtocolV2);
+    Result:=inherited GetBufferForOpHash(True);
   finally
     FSaveSignatureValue:=old;
   end;
@@ -745,8 +746,10 @@ end;
 
 function TOpMultiOperation.N_Operation: Cardinal;
 begin
-  // On a multitoperation, there are N signers, need specify
-  Result := 0;  // Note: N_Operation = 0 means NO OPERATION
+  // On a multioperation, the signer account are senders N accounts, cannot verify which one is correct... will send first one
+  If length(FData.txSenders)>0 then Result := FData.txSenders[0].N_Operation
+  else if (length(FData.changesInfo)>0) then Result := FData.changesInfo[0].N_Operation
+  else Result := 0;
 end;
 
 function TOpMultiOperation.GetAccountN_Operation(account: Cardinal): Cardinal;
@@ -912,17 +915,17 @@ var i : Integer;
 begin
   ssenders := '';
   for i:=low(FData.txSenders) to High(FData.txSenders) do begin
-    ssenders := ssenders + Format('%d:(%s,%s,%d)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.txSenders[i].Account),
+    ssenders := ssenders + Format('%d:(%s;%s;%d)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.txSenders[i].Account),
         TAccountComp.FormatMoney(FData.txSenders[i].Amount),FData.txSenders[i].N_Operation]);
   end;
   sreceivers:='';
   for i:=low(FData.txReceivers) to High(FData.txReceivers) do begin
-    sreceivers := sreceivers + Format('%d:(%s,%s)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.txReceivers[i].Account),
+    sreceivers := sreceivers + Format('%d:(%s;%s)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.txReceivers[i].Account),
         TAccountComp.FormatMoney(FData.txReceivers[i].Amount)]);
   end;
   schanges := '';
   for i:=low(FData.changesInfo) to High(FData.changesInfo) do begin
-    schanges := schanges + Format('%d:(%s,%d)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.changesInfo[i].Account),
+    schanges := schanges + Format('%d:(%s;%d)',[i+1,TAccountComp.AccountNumberToAccountTxtNumber(FData.changesInfo[i].Account),
         FData.changesInfo[i].N_Operation]);
   end;
   Result := Format('Multioperation senders %s receivers %s changes %s Amount:%s Fees:%s',