Browse Source

Merge upstream

Herman Schoenfeld 7 years ago
parent
commit
d35a688295

+ 1 - 1
README.md

@@ -38,7 +38,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
 - TODO: PIP - 0010
 - TODO: Add new network operations
 - New target calc on protocol V3 in order to reduce the sinusoidal effect
-  - On V2, the increase was +-100% every 50 blocks, on V3 will be +-100% every 100 blocks (slower increase/decrease)
+  - On V3 will look last 5 blocks instead of last 10 in order to decide if continue increasing/decreasing target
 - New Safebox Snapshoting
   - This allow quickly rollback/commit directly to Safebox instead of create a separate Safebox on memory (read from disk... use more ram...)
   - Is usefull when detecting posible orphan blocks in order to check which chain is the highest chain without duplicating a safebox to compare

+ 9 - 18
src/core/UAccounts.pas

@@ -62,7 +62,7 @@ Type
     Class Function GetRewardForNewLine(line_index: Cardinal): UInt64;
     Class Function TargetToCompact(target: TRawBytes): Cardinal;
     Class Function TargetFromCompact(encoded: Cardinal): TRawBytes;
-    Class Function GetNewTarget(vteorical, vreal: Cardinal; Const actualTarget: TRawBytes; protocol_version : Word): TRawBytes;
+    Class Function GetNewTarget(vteorical, vreal: Cardinal; Const actualTarget: TRawBytes): TRawBytes;
     Class Procedure CalcProofOfWork_Part1(const operationBlock : TOperationBlock; out Part1 : TRawBytes);
     Class Procedure CalcProofOfWork_Part3(const operationBlock : TOperationBlock; out Part3 : TRawBytes);
     Class Procedure CalcProofOfWork(const operationBlock : TOperationBlock; out PoW : TRawBytes);
@@ -574,7 +574,7 @@ end;
 
 { TPascalCoinProtocol }
 
-class function TPascalCoinProtocol.GetNewTarget(vteorical, vreal: Cardinal; const actualTarget: TRawBytes; protocol_version : Word): TRawBytes;
+class function TPascalCoinProtocol.GetNewTarget(vteorical, vreal: Cardinal; const actualTarget: TRawBytes): TRawBytes;
 Var
   bnact, bnaux: TBigNum;
   tsTeorical, tsReal, factor1000, factor1000Min, factor1000Max: Int64;
@@ -583,15 +583,10 @@ begin
     and an actual target, calculates a new target
     by % of difference of teorical vs real.
 
-    For Protocols 1 and 2:
     Increment/decrement is adjusted to +-200% in a full CT_CalcNewTargetBlocksAverage round
     ...so each new target is a maximum +-(100% DIV (CT_CalcNewTargetBlocksAverage DIV 2)) of
     previous target. This makes target more stable.
 
-    For Protocol 3:
-    Increment/decrement is adjusted to +-100% in a full CT_CalcNewTargetBlocksAverage round
-    This will increment/decrement slowly and reduce sinusoidal effect
-
     }
   tsTeorical := vteorical;
   tsReal := vreal;
@@ -601,14 +596,8 @@ begin
     1000 is the same that multiply by 2 (+100%), so we limit increase
     in a limit [-500..+1000] for a complete (CT_CalcNewTargetBlocksAverage DIV 2) round }
   if CT_CalcNewTargetBlocksAverage>1 then begin
-    if (protocol_version<=CT_PROTOCOL_2) then begin
-      factor1000Min := (-500) DIV (CT_CalcNewTargetBlocksAverage DIV 2);
-      factor1000Max := (1000) DIV (CT_CalcNewTargetBlocksAverage DIV 2);
-    end else begin
-      // Protocol 3: +-100% in a full CT_CalcNewTargetBlocksAverage
-      factor1000Min := (-500) DIV (CT_CalcNewTargetBlocksAverage);
-      factor1000Max := (1000) DIV (CT_CalcNewTargetBlocksAverage);
-    end;
+    factor1000Min := (-500) DIV (CT_CalcNewTargetBlocksAverage DIV 2);
+    factor1000Max := (1000) DIV (CT_CalcNewTargetBlocksAverage DIV 2);
   end else begin
     factor1000Min := (-500);
     factor1000Max := (1000);
@@ -3261,9 +3250,11 @@ begin
     tsTeorical := (CalcBack * CT_NewLineSecondsAvg);
     tsReal := (ts1 - ts2);
     If (protocolVersion=CT_PROTOCOL_1) then begin
-      Result := TPascalCoinProtocol.GetNewTarget(tsTeorical, tsReal,TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target),protocolVersion);
+      Result := TPascalCoinProtocol.GetNewTarget(tsTeorical, tsReal,TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target));
     end else if (protocolVersion<=CT_PROTOCOL_3) then begin
-      CalcBack := CalcBack DIV CT_CalcNewTargetLimitChange_SPLIT;
+      If (protocolVersion=CT_PROTOCOL_2) then
+        CalcBack := CalcBack DIV CT_CalcNewTargetLimitChange_SPLIT_v2
+      else CalcBack := CalcBack DIV CT_CalcNewTargetLimitChange_SPLIT_v3;
       If CalcBack=0 then CalcBack := 1;
       ts2 := Block(BlocksCount-CalcBack-1).blockchainInfo.timestamp;
       tsTeoricalStop := (CalcBack * CT_NewLineSecondsAvg);
@@ -3275,7 +3266,7 @@ begin
       If ((tsTeorical>tsReal) and (tsTeoricalStop>tsRealStop))
          Or
          ((tsTeorical<tsReal) and (tsTeoricalStop<tsRealStop)) then begin
-        Result := TPascalCoinProtocol.GetNewTarget(tsTeorical, tsReal,TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target),protocolVersion);
+        Result := TPascalCoinProtocol.GetNewTarget(tsTeorical, tsReal,TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target));
       end else begin
         // Nothing to do!
         Result:=TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target);

+ 32 - 21
src/core/UBlockChain.pas

@@ -190,8 +190,6 @@ Type
   Private
     Ftag: integer;
   Protected
-    FSignatureChecked : Boolean; // Improvement TPCOperation speed 2.1.6
-    //
     FPrevious_Signer_updated_block: Cardinal;
     FPrevious_Destination_updated_block : Cardinal;
     FPrevious_Seller_updated_block : Cardinal;
@@ -217,6 +215,7 @@ Type
     function OperationFee: UInt64; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
+    procedure SignerAccounts(list : TList); virtual;
     function IsSignerAccount(account : Cardinal) : Boolean; virtual;
     function IsAffectedAccount(account : Cardinal) : Boolean; virtual;
     function DestinationAccount : Int64; virtual;
@@ -1854,7 +1853,8 @@ begin
       for i := 0 to l.Count - 1 do begin
         P := l[i];
         // Include to hash tree
-        TCrypto.DoSha256(FHashTree+P^.Op.Sha256,FHashTree);
+        // TCrypto.DoSha256(FHashTree+P^.Op.Sha256,FHashTree);  COMPILER BUG 2.1.6: Using FHashTree as a "out" param can be initialized prior to be updated first parameter!
+        FHashTree := TCrypto.DoSha256(FHashTree+P^.Op.Sha256);
       end;
     Finally
       FHashTreeOperations.UnlockList;
@@ -1938,8 +1938,8 @@ Var msCopy : TMemoryStream;
   h : TRawBytes;
   P : POperationHashTreeReg;
   PaccData : POperationsHashAccountsData;
-  i,npos : Integer;
-  auxs : AnsiString;
+  i,npos,iListSigners : Integer;
+  listSigners : TList;
 begin
   msCopy := TMemoryStream.Create;
   try
@@ -1952,15 +1952,14 @@ begin
     P^.Op.FPrevious_Signer_updated_block := op.Previous_Signer_updated_block;
     P^.Op.FPrevious_Destination_updated_block := op.FPrevious_Destination_updated_block;
     P^.Op.FPrevious_Seller_updated_block := op.FPrevious_Seller_updated_block;
-    P^.Op.FHasValidSignature:=op.FHasValidSignature;
-    P^.Op.FSignatureChecked:=op.FSignatureChecked;
-    h := op.Sha256;
+    h := FHashTree + op.Sha256;
     P^.Op.FBufferedSha256:=op.FBufferedSha256;
     P^.Op.tag := list.Count;
     // Improvement TOperationsHashTree speed 2.1.6
     // Include to hash tree (Only if CalcNewHashTree=True)
     If (CalcNewHashTree) And (Length(FHashTree)=32) then begin
-      TCrypto.DoSha256(FHashTree+h,FHashTree);
+      // TCrypto.DoSha256(FHashTree+op.Sha256,FHashTree);  COMPILER BUG 2.1.6: Using FHashTree as a "out" param can be initialized prior to be updated first parameter!
+      TCrypto.DoSha256(h,FHashTree);
     end;
     npos := list.Add(P);
     // Improvement: Will allow to add duplicate Operations, so add only first to orderedBySha
@@ -1970,16 +1969,24 @@ begin
     end;
     // Improvement TOperationsHashTree speed 2.1.6
     // Mantain an ordered Accounts list with data
-    If Not FindOrderedByAccountData(list,op.SignerAccount,i) then begin
-      New(PaccData);
-      PaccData^.account_number:=op.SignerAccount;
-      PaccData^.account_count:=0;
-      PaccData^.account_without_fee:=0;
-      FListOrderedByAccountsData.Insert(i,PaccData);
-    end else PaccData := FListOrderedByAccountsData[i];
-    Inc(PaccData^.account_count);
-    If op.OperationFee=0 then begin
-      Inc(PaccData^.account_without_fee);
+    listSigners := TList.Create;
+    try
+      op.SignerAccounts(listSigners);
+      for iListSigners:=0 to listSigners.Count-1 do begin
+        If Not FindOrderedByAccountData(list,PtrInt(listSigners[iListSigners]),i) then begin
+          New(PaccData);
+          PaccData^.account_number:=PtrInt(listSigners[iListSigners]);
+          PaccData^.account_count:=0;
+          PaccData^.account_without_fee:=0;
+          FListOrderedByAccountsData.Insert(i,PaccData);
+        end else PaccData := FListOrderedByAccountsData[i];
+        Inc(PaccData^.account_count);
+        If op.OperationFee=0 then begin
+          Inc(PaccData^.account_without_fee);
+        end;
+      end;
+    finally
+      listSigners.Free;
     end;
   finally
     msCopy.Free;
@@ -2243,7 +2250,6 @@ end;
 
 constructor TPCOperation.Create;
 begin
-  FSignatureChecked := False;
   FHasValidSignature := False;
   FBufferedSha256:='';
   InitializeData;
@@ -2278,6 +2284,12 @@ begin
   end else Raise Exception.Create('ERROR DEV 20170426-1'); // This should never happen, if good coded
 end;
 
+procedure TPCOperation.SignerAccounts(list: TList);
+begin
+  list.Clear;
+  list.Add(TObject(SignerAccount));
+end;
+
 class function TPCOperation.DecodeOperationHash(const operationHash: TRawBytes;
   var block, account, n_operation: Cardinal; var md160Hash : TRawBytes) : Boolean;
   { Decodes a previously generated OperationHash }
@@ -2354,7 +2366,6 @@ begin
   FPrevious_Seller_updated_block := 0;
   FHasValidSignature := false;
   FBufferedSha256:='';
-  FSignatureChecked := False;
 end;
 
 procedure TPCOperation.FillOperationResume(Block: Cardinal; getInfoForAllAccounts : Boolean; Affected_account_number: Cardinal; var OperationResume: TOperationResume);

+ 3 - 2
src/core/UConst.pas

@@ -65,7 +65,8 @@ Const
   CT_MinCompactTarget: Cardinal = {$IFDEF PRODUCTION}$19000000{$ELSE}{$IFDEF TESTNET}$17000000{$ELSE}{$ENDIF}{$ENDIF}; // First compact target of block 0
 
   CT_CalcNewTargetBlocksAverage: Cardinal = 100;
-  CT_CalcNewTargetLimitChange_SPLIT = 10;
+  CT_CalcNewTargetLimitChange_SPLIT_v2 = 10;
+  CT_CalcNewTargetLimitChange_SPLIT_v3 = 20;
 
   CT_MaxAccount : Cardinal = $FFFFFFFF;
   CT_MaxBlock : Cardinal = $FFFFFFFF;
@@ -100,7 +101,7 @@ Const
   CT_Protocol_Upgrade_v3_MinBlock = {$IFDEF PRODUCTION}210000{$ELSE}250{$ENDIF};
 
 
-  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$03000000{$ENDIF}; // Unix timestamp 168048000 ... It's Albert birthdate!
+  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$03000020{$ENDIF}; // Unix timestamp 168048000 ... It's Albert birthdate!
 
   CT_NetProtocol_Version: Word = $0006; // Version 2.1.2 only allows net protocol 6 (Introduced on 2.0.0)
   // IMPORTANT NOTE!!!

+ 1 - 1
src/core/UFileStorage.pas

@@ -309,7 +309,7 @@ begin
   Try
     fs := GetPendingBufferOperationsStream;
     fs.Position:=0;
-    If OperationsHashTree.LoadOperationsHashTreeFromStream(fs,true,CT_PROTOCOL_2,Nil,errors) then begin
+    If OperationsHashTree.LoadOperationsHashTreeFromStream(fs,true,CT_PROTOCOL_3,Nil,errors) then begin
       TLog.NewLog(ltInfo,ClassName,Format('DoLoadPendingBufferOperations loaded operations:%d',[OperationsHashTree.OperationsCount]));
     end else TLog.NewLog(ltError,ClassName,Format('DoLoadPendingBufferOperations ERROR: loaded operations:%d errors:%s',[OperationsHashTree.OperationsCount,errors]));
   finally

+ 21 - 60
src/core/UOpTransaction.pas

@@ -506,19 +506,11 @@ begin
     end;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
   If (public_key in FData.changes_type) then begin
@@ -607,7 +599,6 @@ begin
   end else begin
     FHasValidSignature := true;
   end;
-  FSignatureChecked:=True;
 end;
 
 function TOpChangeAccountInfo.toString: String;
@@ -658,7 +649,6 @@ begin
   end else begin
     FHasValidSignature := true;
   end;
-  FSignatureChecked:=True;
 end;
 
 function TOpTransaction.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -736,20 +726,12 @@ begin
   end;
 
   // Check signature
-  If Not FSignatureChecked then begin
-    _h := GetTransactionHashToSign(FData);
-    if (Not TCrypto.ECDSAVerify(sender.accountInfo.accountkey,_h,FData.sign)) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      Exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  _h := GetTransactionHashToSign(FData);
+  if (Not TCrypto.ECDSAVerify(sender.accountInfo.accountkey,_h,FData.sign)) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    Exit;
+  end else FHasValidSignature := true;
   //
   FPrevious_Signer_updated_block := sender.updated_block;
   FPrevious_Destination_updated_block := target.updated_block;
@@ -1084,7 +1066,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new Change key');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpChangeKey.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -1168,19 +1149,11 @@ begin
     end;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
 
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
@@ -1393,7 +1366,6 @@ begin
   FData.n_operation := n_operation;
   FData.fee := fee;
   FHasValidSignature := true; // Recover founds doesn't need a signature
-  FSignatureChecked := True;
 end;
 
 function TOpRecoverFounds.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -1623,19 +1595,11 @@ begin
     exit;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
 
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
@@ -1872,7 +1836,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new list account for sale operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpListAccountForSale.IsDelist: Boolean;
@@ -1900,7 +1863,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a delist account operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpDelistAccountForSale.IsDelist: Boolean;
@@ -1936,7 +1898,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new Buy operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 procedure TOpBuyAccount.InitializeData;

+ 21 - 0
src/core/UPoolMinerThreads.pas

@@ -716,13 +716,20 @@ Var
   resultPoW : TRawBytes;
   //
   AuxStats : TMinerStats;
+  dstep : Integer;
 begin
+  DebugStep := '----------';
   AuxStats := CT_TMinerStats_NULL;
   nonce := 0;
+  dstep := 0;
+  Try
     while (Not Terminated) do begin
+      Try
+      dstep := 1;
       AuxStats := CT_TMinerStats_NULL;
       If (FCPUDeviceThread.Paused) then sleep(1)
       else begin
+        dstep := 2;
         FLock.Acquire;
         try
           baseRealTC := GetTickCount;
@@ -735,6 +742,7 @@ begin
               FDigestStreamMsg.Position:=FDigestStreamMsg.Size - 8;
               FDigestStreamMsg.Write(ts,4);
               baseHashingTC:=GetTickCount;
+              dstep := 4;
               for i := 1 to CT_Rounds do begin
                 FDigestStreamMsg.Position := FDigestStreamMsg.Size - 4;
                 FDigestStreamMsg.Write(nonce,4);
@@ -742,12 +750,16 @@ begin
                 if resultPoW < FCPUDeviceThread.FMinerValuesForWork.target_pow then begin
                   if Terminated then exit;
                   inc(AuxStats.WinsCount);
+                  dstep := 5;
                   FLock.Release;
                   try
+                    dstep := 6;
                     FCPUDeviceThread.FoundNOnce(ts,nonce);
+                    dstep := 7;
                   finally
                     FLock.Acquire;
                   end;
+                  dstep := 8;
                 end;
                 if (nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
               end;
@@ -774,13 +786,22 @@ begin
             AuxStats.RoundsCount:=CT_Rounds;
             AuxStats.WorkingMillisecondsTotal:=GetTickCount - baseRealTC;
             AuxStats.WorkingMillisecondsHashing:= finalHashingTC - baseHashingTC;
+            dstep := 9;
             FCPUDeviceThread.UpdateDeviceStats(AuxStats);
           end; // FDigestStreamMsg.size>8
         finally
           FLock.Release;
         end;
       end; // Not paused
+      Except
+        On E:Exception do begin
+          TLog.NewLog(ltError,ClassName,'EXCEPTION step:'+IntToStr(dstep)+' ' +E.ClassName+':'+E.Message);
+        end;
+      end;
     end; // while
+  Finally
+    DebugStep := IntToStr(dstep);
+  End;
 end;
 
 constructor TCPUOpenSSLMinerThread.Create(CPUDeviceThread : TCPUDeviceThread);

+ 14 - 16
src/core/UTxMultiOperation.pas

@@ -121,6 +121,7 @@ Type
     function OperationFee : UInt64; override;
     function OperationPayload : TRawBytes; override;
     function SignerAccount : Cardinal; override;
+    procedure SignerAccounts(list : TList); override;
     function IsSignerAccount(account : Cardinal) : Boolean; override;
     function DestinationAccount : Int64; override;
     function SellerAccount : Int64; override;
@@ -333,7 +334,6 @@ begin
   SetLength(FData.changesInfo,0);
   FTotalAmount:=0;
   FTotalFee:=0;
-  FSignatureChecked:=False;
   FHasValidSignature:=False;
 
   SetLength(txsenders,0);
@@ -430,7 +430,6 @@ var i : Integer;
   ophtosign : TRawBytes;
 begin
   // Init
-  FSignatureChecked:=True;
   FHasValidSignature:=False;
   SetLength(errors,0);
   // Do check it!
@@ -620,14 +619,7 @@ begin
     end;
   end;
   // Check signatures!
-  If Not FSignatureChecked then begin
-    If Not CheckSignatures(AccountTransaction,errors) then Exit;
-  end else begin
-    If Not FHasValidSignature then begin
-      Errors := 'Not valid signatures found!';
-      Exit;
-    end;
-  end;
+  If Not CheckSignatures(AccountTransaction,errors) then Exit;
   // Execute!
   If (length(senders)>0) then begin
     If Not AccountTransaction.TransferAmounts(AccountPreviousUpdatedBlock,
@@ -741,7 +733,6 @@ begin
     end;
   end;
   If (Result>0) Then begin
-    FSignatureChecked := False;
     FHasValidSignature := False;
   end;
 end;
@@ -775,6 +766,18 @@ begin
   else Result := MaxInt;
 end;
 
+procedure TOpMultiOperation.SignerAccounts(list: TList);
+var i : Integer;
+begin
+  list.Clear;
+  for i := 0 to High(FData.txSenders) do begin
+    list.Add(TObject(FData.txSenders[i].Account));
+  end;
+  for i:= 0 to High(FData.changesInfo) do begin
+    if list.IndexOf(TObject(FData.changesInfo[i].Account))<0 then list.Add(TObject(FData.changesInfo[i].Account));
+  end;
+end;
+
 function TOpMultiOperation.IsSignerAccount(account: Cardinal): Boolean;
 begin
   // This function will override previous due it can be Multi signed
@@ -844,7 +847,6 @@ begin
   AddTx(senders,receivers,True);
   AddChangeInfos(changes,True);
   // Protection for "Exit"
-  FSignatureChecked:=True;
   FHasValidSignature:=False;
   If (length(senders_keys)<>length(senders)) then exit; // Cannot sign!
   If (length(changes_keys)<>length(changes)) then exit; // Cannot sign!
@@ -860,8 +862,6 @@ begin
       Exit;
     end;
   end;
-  FSignatureChecked:=False;
-  FHasValidSignature:=False;
 end;
 
 function TOpMultiOperation.AddTx(const senders: TMultiOpSenders; const receivers: TMultiOpReceivers; setInRandomOrder : Boolean) : Boolean;
@@ -884,7 +884,6 @@ begin
   end;
   // Ok, let's go
   FHasValidSignature:=False;
-  FSignatureChecked:=False;
   If setInRandomOrder then begin
     // Important:
     // When a sender/receiver is added, everybody must sign again
@@ -942,7 +941,6 @@ begin
   end;
   // Ok, let's go
   FHasValidSignature:=False;
-  FSignatureChecked:=False;
   // Important:
   // When a change is added, everybody must sign again
   // In order to create high anonymity, will add in random order

+ 1 - 1
src/pascalcoin_daemon.lpi

@@ -45,7 +45,7 @@
     </Target>
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir)"/>
-      <OtherUnitFiles Value="core;libraries\synapse;common"/>
+      <OtherUnitFiles Value="core;libraries\synapse;libraries\pascalcoin"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     <CodeGeneration>