|
@@ -89,43 +89,11 @@ type
|
|
|
procedure FetchAll(const AContainer: TList<TOperationResume>); override;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
- TBlockChainData = record
|
|
|
- Block: cardinal;
|
|
|
- Timestamp: cardinal;
|
|
|
- BlockProtocolVersion,
|
|
|
- BlockProtocolAvailable: word;
|
|
|
- OperationsCount: integer;
|
|
|
- Volume: int64;
|
|
|
- Reward, Fee: int64;
|
|
|
- Target: cardinal;
|
|
|
- HashRateTargetKhs: int64;
|
|
|
- HashRateKhs: int64;
|
|
|
- MinerPayload: TRawBytes;
|
|
|
- PoW: TRawBytes;
|
|
|
- SafeBoxHash: TRawBytes;
|
|
|
- AccumulatedWork: UInt64;
|
|
|
- TimeAverage200: real;
|
|
|
- TimeAverage150: real;
|
|
|
- TimeAverage100: real;
|
|
|
- TimeAverage75: real;
|
|
|
- TimeAverage50: real;
|
|
|
- TimeAverage25: real;
|
|
|
- TimeAverage10: real;
|
|
|
- end;
|
|
|
-
|
|
|
-const
|
|
|
- CT_TBlockChainData_NUL: TBlockChainData = (Block: 0; Timestamp: 0; BlockProtocolVersion: 0; BlockProtocolAvailable: 0; OperationsCount: -1; Volume: -1; Reward: 0; Fee: 0; Target: 0; HashRateTargetKhs: 0; HashRateKhs: 0; MinerPayload: ''; PoW: ''; SafeBoxHash: ''; AccumulatedWork: 0; TimeAverage200: 0; TimeAverage150: 0; TimeAverage100: 0; TimeAverage75: 0; TimeAverage50: 0; TimeAverage25: 0; TimeAverage10: 0);
|
|
|
-
|
|
|
-{ TBlockChainGrid }
|
|
|
-
|
|
|
-type
|
|
|
- TShowHashRateAs = (hr_Kilo, hr_Mega, hr_Giga, hr_Tera);
|
|
|
-
|
|
|
-
|
|
|
{ TBlockChainDataSourceBase }
|
|
|
|
|
|
TBlockChainDataSourceBase = class(TCustomDataSource<TBlockChainData>)
|
|
|
+ public type
|
|
|
+ TShowHashRateAs = (hr_Kilo, hr_Mega, hr_Giga, hr_Tera);
|
|
|
private
|
|
|
FStart, FEnd: cardinal;
|
|
|
FHashRateAs: TShowHashRateAs;
|
|
@@ -151,219 +119,11 @@ type
|
|
|
procedure FetchAll(const AContainer: TList<TBlockChainData>); override;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
|
Math, UCoreUtils, UWallet, UTime;
|
|
|
|
|
|
-{ TBlockChainDataSource }
|
|
|
-
|
|
|
-procedure TBlockChainDataSource.FetchAll(const AContainer: TList<TBlockChainData>);
|
|
|
-var
|
|
|
- LStart, LEnd, LIdx: cardinal;
|
|
|
- LOperationComp: TPCOperationsComp;
|
|
|
- LBlockChainData: TBlockChainData;
|
|
|
- LOperationBlock: TOperationBlock;
|
|
|
- LBigNum: TBigNum;
|
|
|
- LNode: TNode;
|
|
|
-begin
|
|
|
-
|
|
|
- LNode := TNode.Node;
|
|
|
- if not Assigned(LNode) then
|
|
|
- Exit;
|
|
|
- if LNode.Bank.BlocksCount <= 0 then
|
|
|
- Exit;
|
|
|
- LEnd := EndBlock;
|
|
|
- LStart := StartBlock;
|
|
|
- LOperationComp := TPCOperationsComp.Create(nil);
|
|
|
- try
|
|
|
- LOperationComp.bank := LNode.Bank;
|
|
|
-
|
|
|
- for LIdx := LEnd downto LStart do
|
|
|
- begin
|
|
|
- LBlockChainData := CT_TBlockChainData_NUL;
|
|
|
- LOperationBlock := LNode.Bank.SafeBox.Block(LIdx).blockchainInfo;
|
|
|
- LBlockChainData.Block := LOperationBlock.block;
|
|
|
- LBlockChainData.Timestamp := LOperationBlock.timestamp;
|
|
|
- LBlockChainData.BlockProtocolVersion := LOperationBlock.protocol_version;
|
|
|
- LBlockChainData.BlockProtocolAvailable := LOperationBlock.protocol_available;
|
|
|
- LBlockChainData.Reward := LOperationBlock.reward;
|
|
|
- LBlockChainData.Fee := LOperationBlock.fee;
|
|
|
- LBlockChainData.Target := LOperationBlock.compact_target;
|
|
|
- LBlockChainData.HashRateKhs := LNode.Bank.SafeBox.CalcBlockHashRateInKhs(LBlockChainData.Block, HashRateAverageBlocksCount);
|
|
|
- LBigNum := TBigNum.TargetToHashRate(LOperationBlock.compact_target);
|
|
|
- try
|
|
|
- LBlockChainData.HashRateTargetKhs := LBigNum.Divide(1024).Divide(CT_NewLineSecondsAvg).Value;
|
|
|
- finally
|
|
|
- LBigNum.Free;
|
|
|
- end;
|
|
|
- LBlockChainData.MinerPayload := LOperationBlock.block_payload;
|
|
|
- LBlockChainData.PoW := LOperationBlock.proof_of_work;
|
|
|
- LBlockChainData.SafeBoxHash := LOperationBlock.initial_safe_box_hash;
|
|
|
- LBlockChainData.AccumulatedWork := LNode.Bank.SafeBox.Block(LBlockChainData.Block).AccumulatedWork;
|
|
|
- if (LNode.Bank.LoadOperations(LOperationComp, LIdx)) then
|
|
|
- begin
|
|
|
- LBlockChainData.OperationsCount := LOperationComp.Count;
|
|
|
- LBlockChainData.Volume := LOperationComp.OperationsHashTree.TotalAmount + LOperationComp.OperationsHashTree.TotalFee;
|
|
|
- end;
|
|
|
- LBlockChainData.TimeAverage200 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 200);
|
|
|
- LBlockChainData.TimeAverage150 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 150);
|
|
|
- LBlockChainData.TimeAverage100 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 100);
|
|
|
- LBlockChainData.TimeAverage75 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 75);
|
|
|
- LBlockChainData.TimeAverage50 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 50);
|
|
|
- LBlockChainData.TimeAverage25 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 25);
|
|
|
- LBlockChainData.TimeAverage10 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 10);
|
|
|
- AContainer.Add(LBlockChainData);
|
|
|
- end;
|
|
|
- finally
|
|
|
- LOperationComp.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-{ TBlockChainDataSourceBase }
|
|
|
-
|
|
|
-function TBlockChainDataSourceBase.GetTimeSpan: TTimeSpan;
|
|
|
-begin
|
|
|
- Result := TTimeSpan.FromSeconds(CT_NewLineSecondsAvg * (FEnd - FStart + 1));
|
|
|
-end;
|
|
|
-
|
|
|
-procedure TBlockChainDataSourceBase.SetTimeSpan(const ASpan: TTimeSpan);
|
|
|
-var
|
|
|
- LNode: TNode;
|
|
|
-begin
|
|
|
- LNode := TNode.Node;
|
|
|
- if not Assigned(LNode) then
|
|
|
- exit;
|
|
|
- FEnd := LNode.Bank.BlocksCount - 1;
|
|
|
- FStart := ClipValue(FEnd - (ASpan.TotalBlockCount + 1), 0, FEnd);
|
|
|
-end;
|
|
|
-
|
|
|
-function TBlockChainDataSourceBase.GetColumns: TDataColumns;
|
|
|
-var
|
|
|
- LHashType: string;
|
|
|
-begin
|
|
|
- case HashRateAs of
|
|
|
- hr_Kilo: LHashType := 'Kh/s';
|
|
|
- hr_Mega: LHashType := 'Mh/s';
|
|
|
- hr_Giga: LHashType := 'Gh/s';
|
|
|
- hr_Tera: LHashType := 'Th/s';
|
|
|
- else
|
|
|
- LHashType := '?h/s';
|
|
|
- end;
|
|
|
- Result := TDataColumns.Create(
|
|
|
- TDataColumn.From('UnixTime'),
|
|
|
- TDataColumn.From('Time'),
|
|
|
- TDataColumn.From('Block'),
|
|
|
- TDataColumn.From('Ops'),
|
|
|
- TDataColumn.From(LHashType),
|
|
|
- TDataColumn.From('Volume'),
|
|
|
- TDataColumn.From('Reward'),
|
|
|
- TDataColumn.From('Fee'),
|
|
|
- TDataColumn.From('FeeDecimal'),
|
|
|
- TDataColumn.From('Target'),
|
|
|
- TDataColumn.From('MinerPayload'),
|
|
|
- TDataColumn.From('POW'),
|
|
|
- TDataColumn.From('SBH'),
|
|
|
- TDataColumn.From('Protocol'),
|
|
|
- TDataColumn.From('Deviation'),
|
|
|
- TDataColumn.From('TimeAverage')
|
|
|
- );
|
|
|
-end;
|
|
|
-
|
|
|
-constructor TBlockChainDataSourceBase.Create(AOwner: TComponent);
|
|
|
-var
|
|
|
- LNode: TNode;
|
|
|
-begin
|
|
|
- inherited Create(AOwner);
|
|
|
- LNode := TNode.Node;
|
|
|
- if Assigned(LNode) then
|
|
|
- begin
|
|
|
- FStart := 0;
|
|
|
- FEnd := LNode.Bank.BlocksCount - 1;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- FStart := 0;
|
|
|
- FEnd := 0;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-function TBlockChainDataSourceBase.GetItemField(constref AItem: TBlockChainData; const ABindingName: ansistring): variant;
|
|
|
-var
|
|
|
- LHR_Base: int64;
|
|
|
- LHashType: string;
|
|
|
- LDeviation: double;
|
|
|
-begin
|
|
|
- case FHashRateAs of
|
|
|
- hr_Kilo: LHashType := 'Kh/s';
|
|
|
- hr_Mega: LHashType := 'Mh/s';
|
|
|
- hr_Giga: LHashType := 'Gh/s';
|
|
|
- hr_Tera: LHashType := 'Th/s';
|
|
|
- else
|
|
|
- LHashType := '?h/s';
|
|
|
- end;
|
|
|
- //if ABindingName = 'UnixTime' then
|
|
|
- // Result := DateTimeToStr(UnivDateTime2LocalDateTime(UnixToUnivDateTime((AItem.Timestamp))))
|
|
|
- //else if ABindingName = 'Time' then
|
|
|
- // Result := DateTimeToStr(UnivDateTime2LocalDateTime(UnixToUnivDateTime((AItem.Timestamp))))
|
|
|
- if ABindingName = 'UnixTime' then
|
|
|
- Result := AItem.Timestamp
|
|
|
- else if ABindingName = 'Time' then
|
|
|
- Result := UnixTimeToLocalStr(AItem.Timestamp)
|
|
|
- else if ABindingName = 'Block' then
|
|
|
- Result := AItem.Block
|
|
|
- else if ABindingName = 'Ops' then
|
|
|
- Result := AItem.OperationsCount
|
|
|
- else if ABindingName = 'Volume' then
|
|
|
- Result := TAccountComp.FormatMoney(AItem.Volume)
|
|
|
- else if ABindingName = 'Reward' then
|
|
|
- Result := TAccountComp.FormatMoney(AItem.Reward)
|
|
|
- else if ABindingName = 'Fee' then
|
|
|
- Result := AItem.Fee
|
|
|
- else if ABindingName = 'FeeDecimal' then
|
|
|
- Result := TAccountComp.FormatMoneyDecimal(AItem.Fee)
|
|
|
- else if ABindingName = 'Target' then
|
|
|
- Result := IntToHex(AItem.Target, 8)
|
|
|
- else if ABindingName = LHashType then
|
|
|
- begin
|
|
|
-
|
|
|
- case HashRateAs of
|
|
|
- hr_Kilo: LHR_Base := 1;
|
|
|
- hr_Mega: LHR_Base := 1000;
|
|
|
- hr_Giga: LHR_Base := 1000000;
|
|
|
- hr_Tera: LHR_Base := 1000000000;
|
|
|
- else
|
|
|
- Result := 1;
|
|
|
- end;
|
|
|
- Result := Format('%.2n (%.2n)', [AItem.HashRateKhs / LHR_Base, AItem.HashRateTargetKhs / LHR_Base]);
|
|
|
- end
|
|
|
- else if ABindingName = 'MinerPayload' then
|
|
|
- begin
|
|
|
- if TCrypto.IsHumanReadable(AItem.MinerPayload) then
|
|
|
- Result := AItem.MinerPayload
|
|
|
- else
|
|
|
- Result := TCrypto.ToHexaString(AItem.MinerPayload);
|
|
|
- end
|
|
|
- else if ABindingName = 'POW' then
|
|
|
- Result := TCrypto.ToHexaString(AItem.PoW)
|
|
|
- else if ABindingName = 'SBH' then
|
|
|
- Result := TCrypto.ToHexaString(AItem.SafeBoxHash)
|
|
|
- else if ABindingName = 'Protocol' then
|
|
|
- Result := IntToStr(AItem.BlockProtocolVersion) + '-' + IntToStr(AItem.BlockProtocolAvailable)
|
|
|
- else if ABindingName = 'Deviation' then
|
|
|
- begin
|
|
|
- LDeviation := ((CT_NewLineSecondsAvg - AItem.TimeAverage100) / CT_NewLineSecondsAvg) * 100;
|
|
|
- Result := Format('%.2f', [LDeviation]) + ' %';
|
|
|
- end
|
|
|
- else if ABindingName = 'TimeAverage' then
|
|
|
- Result := Format('200:%.1f 150:%.1f 100:%.1f 75:%.1f 50:%.1f 25:%.1f 10:%.1f', [AItem.TimeAverage200,
|
|
|
- AItem.TimeAverage150, AItem.TimeAverage100, AItem.TimeAverage75, AItem.TimeAverage50, AItem.TimeAverage25, AItem.TimeAverage10])
|
|
|
- else
|
|
|
- raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
|
|
|
-end;
|
|
|
-
|
|
|
{ TAccountsDataSourceBase }
|
|
|
|
|
|
function TAccountsDataSourceBase.GetColumns: TDataColumns;
|
|
@@ -382,7 +142,7 @@ begin
|
|
|
TDataColumn.From('PriceDecimal'),
|
|
|
TDataColumn.From('LockedUntil'),
|
|
|
TDataColumn.From('NumberOfOperations')
|
|
|
- );
|
|
|
+ );
|
|
|
end;
|
|
|
|
|
|
function TAccountsDataSourceBase.GetItemField(constref AItem: TAccount; const ABindingName: ansistring): variant;
|
|
@@ -459,8 +219,8 @@ begin
|
|
|
for i := 0 to safeBox.AccountsCount - 1 do
|
|
|
AContainer.Add(safeBox.Account(i)) // Load all accounts
|
|
|
else
|
|
|
- for i := 0 to safeBox.AccountsCount - 1 do
|
|
|
- begin // Load key-matching accounts
|
|
|
+ for i := 0 to safeBox.AccountsCount - 1 do begin
|
|
|
+ // Load key-matching accounts
|
|
|
if FIncludePending then
|
|
|
acc := TNode.Node.Operations.SafeBoxTransaction.Account(i)
|
|
|
else
|
|
@@ -481,14 +241,11 @@ var
|
|
|
LAccs: TArray<TAccount>;
|
|
|
begin
|
|
|
LAccs := TWallet.Keys.AccountsKeyList.GetAccounts(FIncludePending);
|
|
|
- if FKeys.Count > 0 then
|
|
|
- begin
|
|
|
+ if FKeys.Count > 0 then begin
|
|
|
for i := Low(LAccs) to High(LAccs) do
|
|
|
if FKeys.Contains(LAccs[i].accountInfo.accountKey) then
|
|
|
AContainer.Add(LAccs[i]);
|
|
|
- end
|
|
|
- else
|
|
|
- AContainer.AddRange(LAccs);
|
|
|
+ end else AContainer.AddRange(LAccs);
|
|
|
end;
|
|
|
|
|
|
{ TOperationsDataSourceBase }
|
|
@@ -499,13 +256,10 @@ var
|
|
|
begin
|
|
|
inherited Create(AOwner);
|
|
|
node := TNode.Node;
|
|
|
- if Assigned(Node) then
|
|
|
- begin
|
|
|
+ if Assigned(Node) then begin
|
|
|
FStart := 0;
|
|
|
FEnd := node.Bank.BlocksCount - 1;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
+ end else begin
|
|
|
FStart := 0;
|
|
|
FEnd := 0;
|
|
|
end;
|
|
@@ -716,22 +470,207 @@ begin
|
|
|
for block := FEnd downto FStart do
|
|
|
begin /// iterate blocks correctly
|
|
|
opr := CT_TOperationResume_NUL;
|
|
|
- if (Node.Bank.Storage.LoadBlockChainBlock(blockOps, block)) then
|
|
|
- begin
|
|
|
+ if (Node.Bank.Storage.LoadBlockChainBlock(blockOps, block)) then begin
|
|
|
AContainer.Add(blockOps.GetMinerRewardPseudoOperation);
|
|
|
// if blockOps.Count = 0 then exit;
|
|
|
for i := blockOps.Count - 1 downto 0 do
|
|
|
- if TPCOperation.OperationToOperationResume(block, blockOps.Operation[i], False, blockOps.Operation[i].SignerAccount, opr) then
|
|
|
- begin
|
|
|
+ if TPCOperation.OperationToOperationResume(block, blockOps.Operation[i], False, blockOps.Operation[i].SignerAccount, opr) then begin
|
|
|
opr.NOpInsideBlock := i;
|
|
|
opr.Block := block;
|
|
|
opr.time := blockOps.OperationBlock.timestamp;
|
|
|
AContainer.Add(opr);
|
|
|
- end// reverse order
|
|
|
- ;
|
|
|
- end
|
|
|
+ end; // reverse order
|
|
|
+ end else break;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ TBlockChainDataSourceBase }
|
|
|
+
|
|
|
+function TBlockChainDataSourceBase.GetTimeSpan: TTimeSpan;
|
|
|
+begin
|
|
|
+ Result := TTimeSpan.FromSeconds(CT_NewLineSecondsAvg * (FEnd - FStart + 1));
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TBlockChainDataSourceBase.SetTimeSpan(const ASpan: TTimeSpan);
|
|
|
+var
|
|
|
+ LNode: TNode;
|
|
|
+begin
|
|
|
+ LNode := TNode.Node;
|
|
|
+ if not Assigned(LNode) then
|
|
|
+ exit;
|
|
|
+ FEnd := LNode.Bank.BlocksCount - 1;
|
|
|
+ FStart := ClipValue(FEnd - (ASpan.TotalBlockCount + 1), 0, FEnd);
|
|
|
+end;
|
|
|
+
|
|
|
+function TBlockChainDataSourceBase.GetColumns: TDataColumns;
|
|
|
+var
|
|
|
+ LHashType: string;
|
|
|
+begin
|
|
|
+ case HashRateAs of
|
|
|
+ hr_Kilo: LHashType := 'Kh/s';
|
|
|
+ hr_Mega: LHashType := 'Mh/s';
|
|
|
+ hr_Giga: LHashType := 'Gh/s';
|
|
|
+ hr_Tera: LHashType := 'Th/s';
|
|
|
+ else LHashType := '?h/s';
|
|
|
+ end;
|
|
|
+ Result := TDataColumns.Create(
|
|
|
+ TDataColumn.From('UnixTime'),
|
|
|
+ TDataColumn.From('Time'),
|
|
|
+ TDataColumn.From('Block'),
|
|
|
+ TDataColumn.From('Ops'),
|
|
|
+ TDataColumn.From(LHashType),
|
|
|
+ TDataColumn.From('Volume'),
|
|
|
+ TDataColumn.From('Reward'),
|
|
|
+ TDataColumn.From('Fee'),
|
|
|
+ TDataColumn.From('FeeDecimal'),
|
|
|
+ TDataColumn.From('Target'),
|
|
|
+ TDataColumn.From('MinerPayload'),
|
|
|
+ TDataColumn.From('POW'),
|
|
|
+ TDataColumn.From('SBH'),
|
|
|
+ TDataColumn.From('Protocol'),
|
|
|
+ TDataColumn.From('Deviation'),
|
|
|
+ TDataColumn.From('TimeAverage')
|
|
|
+ );
|
|
|
+end;
|
|
|
+
|
|
|
+constructor TBlockChainDataSourceBase.Create(AOwner: TComponent);
|
|
|
+var
|
|
|
+ LNode: TNode;
|
|
|
+begin
|
|
|
+ inherited Create(AOwner);
|
|
|
+ LNode := TNode.Node;
|
|
|
+ if Assigned(LNode) then begin
|
|
|
+ FStart := 0;
|
|
|
+ FEnd := LNode.Bank.BlocksCount - 1;
|
|
|
+ end else begin
|
|
|
+ FStart := 0;
|
|
|
+ FEnd := 0;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TBlockChainDataSourceBase.GetItemField(constref AItem: TBlockChainData; const ABindingName: ansistring): variant;
|
|
|
+var
|
|
|
+ LHR_Base: int64;
|
|
|
+ LHashType: string;
|
|
|
+ LDeviation: double;
|
|
|
+begin
|
|
|
+ case FHashRateAs of
|
|
|
+ hr_Kilo: LHashType := 'Kh/s';
|
|
|
+ hr_Mega: LHashType := 'Mh/s';
|
|
|
+ hr_Giga: LHashType := 'Gh/s';
|
|
|
+ hr_Tera: LHashType := 'Th/s';
|
|
|
+ else LHashType := '?h/s';
|
|
|
+ end;
|
|
|
+ //if ABindingName = 'UnixTime' then
|
|
|
+ // Result := DateTimeToStr(UnivDateTime2LocalDateTime(UnixToUnivDateTime((AItem.Timestamp))))
|
|
|
+ //else if ABindingName = 'Time' then
|
|
|
+ // Result := DateTimeToStr(UnivDateTime2LocalDateTime(UnixToUnivDateTime((AItem.Timestamp))))
|
|
|
+ if ABindingName = 'UnixTime' then
|
|
|
+ Result := AItem.Timestamp
|
|
|
+ else if ABindingName = 'Time' then
|
|
|
+ Result := UnixTimeToLocalStr(AItem.Timestamp)
|
|
|
+ else if ABindingName = 'Block' then
|
|
|
+ Result := AItem.Block
|
|
|
+ else if ABindingName = 'Ops' then
|
|
|
+ Result := AItem.OperationsCount
|
|
|
+ else if ABindingName = 'Volume' then
|
|
|
+ Result := TAccountComp.FormatMoney(AItem.Volume)
|
|
|
+ else if ABindingName = 'Reward' then
|
|
|
+ Result := TAccountComp.FormatMoney(AItem.Reward)
|
|
|
+ else if ABindingName = 'Fee' then
|
|
|
+ Result := AItem.Fee
|
|
|
+ else if ABindingName = 'FeeDecimal' then
|
|
|
+ Result := TAccountComp.FormatMoneyDecimal(AItem.Fee)
|
|
|
+ else if ABindingName = 'Target' then
|
|
|
+ Result := IntToHex(AItem.Target, 8)
|
|
|
+ else if ABindingName = LHashType then begin
|
|
|
+ case HashRateAs of
|
|
|
+ hr_Kilo: LHR_Base := 1;
|
|
|
+ hr_Mega: LHR_Base := 1000;
|
|
|
+ hr_Giga: LHR_Base := 1000000;
|
|
|
+ hr_Tera: LHR_Base := 1000000000;
|
|
|
+ else
|
|
|
+ Result := 1;
|
|
|
+ end;
|
|
|
+ Result := Format('%.2n (%.2n)', [AItem.HashRateKhs / LHR_Base, AItem.HashRateTargetKhs / LHR_Base]);
|
|
|
+ end else if ABindingName = 'MinerPayload' then begin
|
|
|
+ if TCrypto.IsHumanReadable(AItem.MinerPayload) then
|
|
|
+ Result := AItem.MinerPayload
|
|
|
else
|
|
|
- break;
|
|
|
+ Result := TCrypto.ToHexaString(AItem.MinerPayload);
|
|
|
+ end else if ABindingName = 'POW' then
|
|
|
+ Result := TCrypto.ToHexaString(AItem.PoW)
|
|
|
+ else if ABindingName = 'SBH' then
|
|
|
+ Result := TCrypto.ToHexaString(AItem.SafeBoxHash)
|
|
|
+ else if ABindingName = 'Protocol' then
|
|
|
+ Result := IntToStr(AItem.BlockProtocolVersion) + '-' + IntToStr(AItem.BlockProtocolAvailable)
|
|
|
+ else if ABindingName = 'Deviation' then begin
|
|
|
+ LDeviation := ((CT_NewLineSecondsAvg - AItem.TimeAverage100) / CT_NewLineSecondsAvg) * 100;
|
|
|
+ Result := Format('%.2f', [LDeviation]) + ' %';
|
|
|
+ end else if ABindingName = 'TimeAverage' then
|
|
|
+ Result := Format('200:%.1f 150:%.1f 100:%.1f 75:%.1f 50:%.1f 25:%.1f 10:%.1f', [AItem.TimeAverage200, AItem.TimeAverage150, AItem.TimeAverage100, AItem.TimeAverage75, AItem.TimeAverage50, AItem.TimeAverage25, AItem.TimeAverage10])
|
|
|
+ else
|
|
|
+ raise Exception.Create(Format('Field not found [%s]', [ABindingName]));
|
|
|
+end;
|
|
|
+
|
|
|
+{ TBlockChainDataSource }
|
|
|
+
|
|
|
+procedure TBlockChainDataSource.FetchAll(const AContainer: TList<TBlockChainData>);
|
|
|
+var
|
|
|
+ LStart, LEnd, LIdx: cardinal;
|
|
|
+ LOperationComp: TPCOperationsComp;
|
|
|
+ LBlockChainData: TBlockChainData;
|
|
|
+ LOperationBlock: TOperationBlock;
|
|
|
+ LBigNum: TBigNum;
|
|
|
+ LNode: TNode;
|
|
|
+begin
|
|
|
+ LNode := TNode.Node;
|
|
|
+ if not Assigned(LNode) then
|
|
|
+ Exit;
|
|
|
+ if LNode.Bank.BlocksCount <= 0 then
|
|
|
+ Exit;
|
|
|
+ LEnd := EndBlock;
|
|
|
+ LStart := StartBlock;
|
|
|
+ LOperationComp := TPCOperationsComp.Create(nil);
|
|
|
+ try
|
|
|
+ LOperationComp.bank := LNode.Bank;
|
|
|
+
|
|
|
+ for LIdx := LEnd downto LStart do begin
|
|
|
+ LBlockChainData := CT_TBlockChainData_NUL;
|
|
|
+ LOperationBlock := LNode.Bank.SafeBox.Block(LIdx).blockchainInfo;
|
|
|
+ LBlockChainData.Block := LOperationBlock.block;
|
|
|
+ LBlockChainData.Timestamp := LOperationBlock.timestamp;
|
|
|
+ LBlockChainData.BlockProtocolVersion := LOperationBlock.protocol_version;
|
|
|
+ LBlockChainData.BlockProtocolAvailable := LOperationBlock.protocol_available;
|
|
|
+ LBlockChainData.Reward := LOperationBlock.reward;
|
|
|
+ LBlockChainData.Fee := LOperationBlock.fee;
|
|
|
+ LBlockChainData.Target := LOperationBlock.compact_target;
|
|
|
+ LBlockChainData.HashRateKhs := LNode.Bank.SafeBox.CalcBlockHashRateInKhs(LBlockChainData.Block, HashRateAverageBlocksCount);
|
|
|
+ LBigNum := TBigNum.TargetToHashRate(LOperationBlock.compact_target);
|
|
|
+ try
|
|
|
+ LBlockChainData.HashRateTargetKhs := LBigNum.Divide(1024).Divide(CT_NewLineSecondsAvg).Value;
|
|
|
+ finally
|
|
|
+ LBigNum.Free;
|
|
|
+ end;
|
|
|
+ LBlockChainData.MinerPayload := LOperationBlock.block_payload;
|
|
|
+ LBlockChainData.PoW := LOperationBlock.proof_of_work;
|
|
|
+ LBlockChainData.SafeBoxHash := LOperationBlock.initial_safe_box_hash;
|
|
|
+ LBlockChainData.AccumulatedWork := LNode.Bank.SafeBox.Block(LBlockChainData.Block).AccumulatedWork;
|
|
|
+ if (LNode.Bank.LoadOperations(LOperationComp, LIdx)) then begin
|
|
|
+ LBlockChainData.OperationsCount := LOperationComp.Count;
|
|
|
+ LBlockChainData.Volume := LOperationComp.OperationsHashTree.TotalAmount + LOperationComp.OperationsHashTree.TotalFee;
|
|
|
+ end;
|
|
|
+ LBlockChainData.TimeAverage200 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 200);
|
|
|
+ LBlockChainData.TimeAverage150 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 150);
|
|
|
+ LBlockChainData.TimeAverage100 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 100);
|
|
|
+ LBlockChainData.TimeAverage75 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 75);
|
|
|
+ LBlockChainData.TimeAverage50 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 50);
|
|
|
+ LBlockChainData.TimeAverage25 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 25);
|
|
|
+ LBlockChainData.TimeAverage10 := LNode.Bank.GetTargetSecondsAverage(LBlockChainData.Block, 10);
|
|
|
+ AContainer.Add(LBlockChainData);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ LOperationComp.Free;
|
|
|
end;
|
|
|
end;
|
|
|
|