From d6cd7762c446d59dad338afccb630f75e67d7e78 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 4 Mar 2025 15:24:25 +0100 Subject: [PATCH] Adds proof-period report to chain-events. --- Framework/GethConnector/GethInput.cs | 6 +- .../NethereumWorkflow/NethereumInteraction.cs | 15 +++ .../ChainMonitor/ChainState.cs | 8 ++ .../ChainMonitor/PeriodMonitor.cs | 99 +++++++++++++++++++ .../CodexContractsAccess.cs | 83 +++++++++++++++- .../Marketplace/Marketplace.cs | 2 +- ProjectPlugins/GethPlugin/GethNode.cs | 12 +++ Tools/TestNetRewarder/EventsFormatter.cs | 22 +++++ Tools/TestNetRewarder/HistoricState.cs | 97 ------------------ Tools/TestNetRewarder/Processor.cs | 11 +++ 10 files changed, 252 insertions(+), 103 deletions(-) create mode 100644 ProjectPlugins/CodexContractsPlugin/ChainMonitor/PeriodMonitor.cs delete mode 100644 Tools/TestNetRewarder/HistoricState.cs diff --git a/Framework/GethConnector/GethInput.cs b/Framework/GethConnector/GethInput.cs index 968aec29..6f3e1331 100644 --- a/Framework/GethConnector/GethInput.cs +++ b/Framework/GethConnector/GethInput.cs @@ -45,7 +45,11 @@ private static string? GetEnvVar(List error, string name) { var result = Environment.GetEnvironmentVariable(name); - if (string.IsNullOrEmpty(result)) error.Add($"'{name}' is not set."); + if (string.IsNullOrEmpty(result)) + { + error.Add($"'{name}' is not set."); + return null; + } return result.Trim(); } } diff --git a/Framework/NethereumWorkflow/NethereumInteraction.cs b/Framework/NethereumWorkflow/NethereumInteraction.cs index efb2fd56..f79eb199 100644 --- a/Framework/NethereumWorkflow/NethereumInteraction.cs +++ b/Framework/NethereumWorkflow/NethereumInteraction.cs @@ -50,6 +50,21 @@ namespace NethereumWorkflow return Time.Wait(handler.QueryAsync(contractAddress, function)); } + public TResult Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new() + { + log.Debug(typeof(TFunction).ToString()); + var handler = web3.Eth.GetContractQueryHandler(); + return Time.Wait(handler.QueryAsync(contractAddress, function, new BlockParameter(blockNumber))); + } + + public void Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new() + { + log.Debug(typeof(TFunction).ToString()); + var handler = web3.Eth.GetContractQueryHandler(); + var result = Time.Wait(handler.QueryRawAsync(contractAddress, function, new BlockParameter(blockNumber))); + var aaaa = 0; + } + public string SendTransaction(string contractAddress, TFunction function) where TFunction : FunctionMessage, new() { log.Debug(); diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs index 0a04cac2..4c8f35a4 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs @@ -46,10 +46,12 @@ namespace CodexContractsPlugin.ChainMonitor this.contracts = contracts; handler = changeHandler; TotalSpan = new TimeRange(startUtc, startUtc); + PeriodMonitor = new PeriodMonitor(this.log, contracts); } public TimeRange TotalSpan { get; private set; } public IChainStateRequest[] Requests => requests.ToArray(); + public PeriodMonitor PeriodMonitor { get; } public int Update() { @@ -88,11 +90,17 @@ namespace CodexContractsPlugin.ChainMonitor { var blockEvents = events.All.Where(e => e.Block.BlockNumber == b).ToArray(); ApplyEvents(b, blockEvents, eventUtc); + UpdatePeriodMonitor(b, eventUtc); eventUtc += spanPerBlock; } } + private void UpdatePeriodMonitor(ulong blockNumber, DateTime eventUtc) + { + PeriodMonitor.Update(blockNumber, eventUtc, Requests); + } + private void ApplyEvents(ulong blockNumber, IHasBlock[] blockEvents, DateTime eventsUtc) { foreach (var e in blockEvents) diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/PeriodMonitor.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/PeriodMonitor.cs new file mode 100644 index 00000000..5ec8f5d0 --- /dev/null +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/PeriodMonitor.cs @@ -0,0 +1,99 @@ +using Logging; +using Utils; + +namespace CodexContractsPlugin.ChainMonitor +{ + public class PeriodMonitor + { + private readonly ILog log; + private readonly ICodexContracts contracts; + private readonly List reports = new List(); + private ulong? currentPeriod = null; + + public PeriodMonitor(ILog log, ICodexContracts contracts) + { + this.log = log; + this.contracts = contracts; + } + + public void Update(ulong blockNumber, DateTime eventUtc, IChainStateRequest[] requests) + { + var period = contracts.GetPeriodNumber(eventUtc); + if (!currentPeriod.HasValue) + { + currentPeriod = period; + return; + } + if (period == currentPeriod.Value) return; + + CreateReportForPeriod(blockNumber - 1, currentPeriod.Value, requests); + currentPeriod = period; + } + + public PeriodReport[] GetAndClearReports() + { + var result = reports.ToArray(); + reports.Clear(); + return result; + } + + private void CreateReportForPeriod(ulong lastBlockInPeriod, ulong periodNumber, IChainStateRequest[] requests) + { + log.Log("Creating report for period " + periodNumber); + + ulong total = 0; + ulong required = 0; + var missed = new List(); + foreach (var request in requests) + { + for (ulong slotIndex = 0; slotIndex < request.Request.Ask.Slots; slotIndex++) + { + var state = contracts.GetProofState(request.Request, slotIndex, lastBlockInPeriod, periodNumber); + + total++; + if (state.Required) + { + required++; + if (state.Missing) + { + var idx = Convert.ToInt32(slotIndex); + var host = request.Hosts.GetHost(idx); + missed.Add(new PeriodProofMissed(host, request, idx)); + } + } + } + } + reports.Add(new PeriodReport(periodNumber, total, required, missed.ToArray())); + } + } + + public class PeriodReport + { + public PeriodReport(ulong periodNumber, ulong totalNumSlots, ulong totalProofsRequired, PeriodProofMissed[] missedProofs) + { + PeriodNumber = periodNumber; + TotalNumSlots = totalNumSlots; + TotalProofsRequired = totalProofsRequired; + MissedProofs = missedProofs; + } + + public ulong PeriodNumber { get; } + public ulong TotalNumSlots { get; } + public ulong TotalProofsRequired { get; } + public PeriodProofMissed[] MissedProofs { get; } + } + + public class PeriodProofMissed + { + public PeriodProofMissed(EthAddress? host, IChainStateRequest request, int slotIndex) + { + Host = host; + Request = request; + SlotIndex = slotIndex; + } + + public EthAddress? Host { get; } + public IChainStateRequest Request { get; } + public int SlotIndex { get; } + } +} diff --git a/ProjectPlugins/CodexContractsPlugin/CodexContractsAccess.cs b/ProjectPlugins/CodexContractsPlugin/CodexContractsAccess.cs index d7191b7d..4a36bece 100644 --- a/ProjectPlugins/CodexContractsPlugin/CodexContractsAccess.cs +++ b/ProjectPlugins/CodexContractsPlugin/CodexContractsAccess.cs @@ -3,6 +3,8 @@ using CodexContractsPlugin.Marketplace; using GethPlugin; using Logging; using Nethereum.ABI; +using Nethereum.ABI.FunctionEncoding.Attributes; +using Nethereum.Contracts; using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.Util; using NethereumWorkflow; @@ -26,7 +28,21 @@ namespace CodexContractsPlugin ICodexContractsEvents GetEvents(BlockInterval blockInterval); EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex); RequestState GetRequestState(Request request); + ulong GetPeriodNumber(DateTime utc); void WaitUntilNextPeriod(); + ProofState GetProofState(Request storageRequest, decimal slotIndex, ulong blockNumber, ulong period); + } + + public class ProofState + { + public ProofState(bool required, bool missing) + { + Required = required; + Missing = missing; + } + + public bool Required { get; } + public bool Missing { get; } } [JsonConverter(typeof(StringEnumConverter))] @@ -89,19 +105,23 @@ namespace CodexContractsPlugin return new CodexContractsEvents(log, gethNode, Deployment, blockInterval); } - public EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex) + public byte[] GetSlotId(Request request, decimal slotIndex) { var encoder = new ABIEncode(); var encoded = encoder.GetABIEncoded( - new ABIValue("bytes32", storageRequest.RequestId), + new ABIValue("bytes32", request.RequestId), new ABIValue("uint256", slotIndex.ToBig()) ); - var hashed = Sha3Keccack.Current.CalculateHash(encoded); + return Sha3Keccack.Current.CalculateHash(encoded); + } + public EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex) + { + var slotId = GetSlotId(storageRequest, slotIndex); var func = new GetHostFunction { - SlotId = hashed + SlotId = slotId }; var address = gethNode.Call(Deployment.MarketplaceAddress, func); if (string.IsNullOrEmpty(address)) return null; @@ -117,6 +137,15 @@ namespace CodexContractsPlugin return gethNode.Call(Deployment.MarketplaceAddress, func); } + public ulong GetPeriodNumber(DateTime utc) + { + DateTimeOffset utco = DateTime.SpecifyKind(utc, DateTimeKind.Utc); + var now = utco.ToUnixTimeSeconds(); + var periodSeconds = (int)Deployment.Config.Proofs.Period; + var result = now / periodSeconds; + return Convert.ToUInt64(result); + } + public void WaitUntilNextPeriod() { log.Log("Waiting until next proof period..."); @@ -126,6 +155,52 @@ namespace CodexContractsPlugin Thread.Sleep(TimeSpan.FromSeconds(secondsLeft + 1)); } + public ProofState GetProofState(Request storageRequest, decimal slotIndex, ulong blockNumber, ulong period) + { + var slotId = GetSlotId(storageRequest, slotIndex); + + var required = IsProofRequired(slotId, blockNumber); + if (!required) return new ProofState(false, false); + + var missing = IsProofMissing(slotId, blockNumber, period); + return new ProofState(required, missing); + } + + private bool IsProofRequired(byte[] slotId, ulong blockNumber) + { + var func = new IsProofRequiredFunction + { + Id = slotId + }; + var result = gethNode.Call(Deployment.MarketplaceAddress, func, blockNumber); + return result.ReturnValue1; + } + + private bool IsProofMissing(byte[] slotId, ulong blockNumber, ulong period) + { + try + { + var funcB = new MarkProofAsMissingFunction + { + SlotId = slotId, + Period = period + }; + gethNode.Call(Deployment.MarketplaceAddress, funcB, blockNumber); + } + catch (AggregateException exc) + { + if (exc.InnerExceptions.Count == 1) + { + if (exc.InnerExceptions[0].GetType() == typeof(SmartContractCustomErrorRevertException)) + { + return false; + } + } + throw; + } + return true; + } + private ContractInteractions StartInteraction() { return new ContractInteractions(log, gethNode); diff --git a/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs b/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs index d74dd21f..545372f4 100644 --- a/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs +++ b/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs @@ -15,7 +15,7 @@ namespace CodexContractsPlugin.Marketplace public class MarketplaceDeploymentBase : ContractDeploymentMessage { - public static string BYTECODE = "0x60c06040523480156200001157600080fd5b5060405162004e8438038062004e8483398101604081905262000034916200056f565b602083015180516040850151516001805460ff191660ff90921691909117905582906001600160401b038116600003620000815760405163015536c760e51b815260040160405180910390fd5b6001600160401b03166080526101004311620000b0576040516338f5f66160e11b815260040160405180910390fd5b8151600280546020850151604086015160608701516001600160401b039586166001600160801b0319909416939093176801000000000000000095909216949094021761ffff60801b1916600160801b60ff9485160260ff60881b191617600160881b939091169290920291909117815560808301518391906003906200013890826200072d565b5050600480546001600160a01b0319166001600160a01b0393841617905550831660a05250825151606460ff909116111562000187576040516302bd816360e41b815260040160405180910390fd5b606483600001516040015160ff161115620001b5576040516354e5e0ab60e11b815260040160405180910390fd5b82516040810151602090910151606491620001d091620007f9565b60ff161115620001f3576040516317ff9d0f60e21b815260040160405180910390fd5b82518051600b805460208085015160408087015160609788015160ff90811663010000000263ff0000001992821662010000029290921663ffff0000199482166101000261ffff1990971698821698909817959095179290921695909517178355808801518051600c80549383015196830151978301518516600160881b0260ff60881b1998909516600160801b029790971661ffff60801b196001600160401b0397881668010000000000000000026001600160801b031990951697909216969096179290921791909116939093171783556080820151869391929190600d90620002e090826200072d565b50505060408201515160038201805460ff191660ff909216919091179055606090910151600490910180546001600160401b0319166001600160401b03909216919091179055506200082b915050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156200036b576200036b62000330565b60405290565b604051608081016001600160401b03811182821017156200036b576200036b62000330565b604051601f8201601f191681016001600160401b0381118282101715620003c157620003c162000330565b604052919050565b805160ff81168114620003db57600080fd5b919050565b80516001600160401b0381168114620003db57600080fd5b600060a082840312156200040b57600080fd5b6200041562000346565b90506200042282620003e0565b8152602062000433818401620003e0565b818301526200044560408401620003c9565b60408301526200045860608401620003c9565b606083015260808301516001600160401b03808211156200047857600080fd5b818501915085601f8301126200048d57600080fd5b815181811115620004a257620004a262000330565b620004b6601f8201601f1916850162000396565b91508082528684828501011115620004cd57600080fd5b60005b81811015620004ed578381018501518382018601528401620004d0565b5060008482840101525080608085015250505092915050565b6000602082840312156200051957600080fd5b604051602081016001600160401b03811182821017156200053e576200053e62000330565b6040529050806200054f83620003c9565b905292915050565b80516001600160a01b0381168114620003db57600080fd5b6000806000606084860312156200058557600080fd5b83516001600160401b03808211156200059d57600080fd5b9085019081870360e0811215620005b357600080fd5b620005bd62000371565b6080821215620005cc57600080fd5b620005d662000371565b9150620005e384620003c9565b8252620005f360208501620003c9565b60208301526200060660408501620003c9565b60408301526200061960608501620003c9565b6060830152908152608083015190828211156200063557600080fd5b6200064389838601620003f8565b6020820152620006578960a0860162000506565b60408201526200066a60c08501620003e0565b6060820152955062000683925050506020850162000557565b9150620006936040850162000557565b90509250925092565b600181811c90821680620006b157607f821691505b602082108103620006d257634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000728576000816000526020600020601f850160051c81016020861015620007035750805b601f850160051c820191505b8181101562000724578281556001016200070f565b5050505b505050565b81516001600160401b0381111562000749576200074962000330565b62000761816200075a84546200069c565b84620006d8565b602080601f831160018114620007995760008415620007805750858301515b600019600386901b1c1916600185901b17855562000724565b600085815260208120601f198616915b82811015620007ca57888601518255948401946001909101908401620007a9565b5085821015620007e95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60ff81811683821602908116908181146200082457634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a0516145fb62000889600039600081816104bf01528181610f1601528181611fb70152818161252a015281816125da01528181612769015281816128190152612c430152600081816134ad015261373d01526145fb6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80636e2b54ee116100f9578063c0cc4add11610097578063e8aa0a0711610071578063e8aa0a0714610461578063f752196b14610474578063fb1e61ca1461049d578063fc0c546a146104bd57600080fd5b8063c0cc4add14610428578063c5d433511461043b578063d02bbe331461044e57600080fd5b8063a29c29a4116100d3578063a29c29a4146103b2578063a3a0807e146103c5578063b396dc79146103e8578063be5cdc481461040857600080fd5b80636e2b54ee146103845780639777b72c1461039757806399b6da0c1461039f57600080fd5b8063329b5a0b1161016657806351a766421161014057806351a76642146103035780635da73835146103165780636b00c8cf1461032b5780636c70bee91461036f57600080fd5b8063329b5a0b14610298578063458d2bf1146102cb5780634641dce6146102de57600080fd5b806312827602116101a2578063128276021461022e5780631d873c1b14610241578063237d84821461025457806326d6f8341461026757600080fd5b806302fa8e65146101c957806305b90773146101f95780630aefaabe14610219575b600080fd5b6101dc6101d736600461380a565b6104e3565b6040516001600160401b0390911681526020015b60405180910390f35b61020c61020736600461380a565b610573565b6040516101f09190613839565b61022c610227366004613868565b610696565b005b61022c61023c3660046138cf565b610829565b61022c61024f366004613912565b6108fa565b61022c6102623660046138cf565b610da0565b61028a61027536600461380a565b60009081526012602052604090206003015490565b6040519081526020016101f0565b6101dc6102a636600461380a565b600090815260116020526040902060020154600160c01b90046001600160401b031690565b61028a6102d936600461380a565b610fec565b6102f16102ec36600461380a565b611005565b60405160ff90911681526020016101f0565b61028a61031136600461380a565b611018565b61031e61106f565b6040516101f09190613952565b61035761033936600461380a565b6000908152601260205260409020600401546001600160a01b031690565b6040516001600160a01b0390911681526020016101f0565b610377611096565b6040516101f091906139dc565b61022c61039236600461380a565b61120d565b61031e61121a565b61022c6103ad366004613aad565b611239565b61022c6103c036600461380a565b61177f565b6103d86103d336600461380a565b6117d1565b60405190151581526020016101f0565b6103fb6103f636600461380a565b61180d565b6040516101f09190613bcb565b61041b61041636600461380a565b611aef565b6040516101f09190613c06565b6103d861043636600461380a565b611bbd565b61022c610449366004613c1a565b611bd0565b6103d861045c3660046138cf565b612051565b61022c61046f366004613c3f565b6120bd565b6101dc61048236600461380a565b6000908152600660205260409020546001600160401b031690565b6104b06104ab36600461380a565b6121ed565b6040516101f09190613c6d565b7f0000000000000000000000000000000000000000000000000000000000000000610357565b600081815260116020526040812060020154600160801b90046001600160401b03168161050f84610573565b9050600081600481111561052557610525613823565b14806105425750600181600481111561054057610540613823565b145b1561054e575092915050565b61056b6001600160401b038316610566600142613c96565b612403565b949350505050565b60008181526010602052604081205482906001600160a01b03166105aa57604051635eeb253d60e11b815260040160405180910390fd5b600083815260116020526040812090815460ff1660048111156105cf576105cf613823565b14801561060e5750600084815260116020526040902060020154600160c01b90046001600160401b03166001600160401b0316426001600160401b0316115b1561061d576002925050610690565b6001815460ff16600481111561063557610635613823565b148061065657506000815460ff16600481111561065457610654613823565b145b801561067a575060028101546001600160401b03600160801b909104811642909116115b15610689576003925050610690565b5460ff1691505b50919050565b826000808281526012602052604090205460ff1660068111156106bb576106bb613823565b036106d957604051638b41ec7f60e01b815260040160405180910390fd5b600084815260126020526040902060048101546001600160a01b0316331461072d576040517f57a6f4e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061073886611aef565b9050600481600681111561074e5761074e613823565b03610785576040517fc2cbf77700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600281600681111561079957610799613823565b036107b3576107ae826001015487878761241b565b610821565b60058160068111156107c7576107c7613823565b036107dc576107ae8260010154878787612664565b60038160068111156107f0576107f0613823565b036107ff576107ae33876128ad565b600181600681111561081357610813613823565b0361082157610821866128cf565b505050505050565b6108338282612051565b610869576040517f424a04ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108758383612b27565b60008181526020819052604090209091506108909033612b6c565b50600154600082815260208190526040902060ff909116906108b190612b81565b036108f5576040516001600160401b038316815283907fc8e6c955744189a19222ec226b72ac1435d88d5745252dac56e6f679f64c037a9060200160405180910390a25b505050565b60008381526010602052604090205483906001600160a01b031661093157604051635eeb253d60e11b815260040160405180910390fd5b600084815260106020526040902060048101546001600160401b0390811690851610610989576040517f3b920b8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109958686612b27565b60008181526020819052604090209091506109b09033612b8b565b6109e6576040517fd651ce1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152601260209081526040808320600181018a90556002810180546fffffffffffffffff00000000000000001916600160401b6001600160401b038c1602179055898452601190925282209091610a3f84611aef565b6006811115610a5057610a50613823565b14158015610a7857506006610a6484611aef565b6006811115610a7557610a75613823565b14155b15610aaf576040517fff556acf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600560205260409020805467ffffffffffffffff1916426001600160401b0316179055610ae183876120bd565b60048201805473ffffffffffffffffffffffffffffffffffffffff191633179055600280830180546001600160401b0342811667ffffffffffffffff19909216919091179091559082018054600192600091610b3f91859116613ca9565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610b84888360020160009054906101000a90046001600160401b0316612bad565b816001016000828254610b979190613c96565b90915550506040805160e081018252600186015481526002860154602082015260038601549181019190915260048501546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c08201526000908190610c1090612bdc565b90506006610c1d86611aef565b6006811115610c2e57610c2e613823565b03610c6157600b54606490610c469060ff1683613cc9565b610c509190613cf6565b610c5a9082613c96565b9150610c65565b8091505b610c6f3383612bfb565b8160136000016000828254610c849190613d0a565b9091555050600384018190556004840154610ca8906001600160a01b031686612ccf565b835460ff191660011784556040516001600160401b038a1681528a907f8f301470a994578b52323d625dfbf827ca5208c81747d3459be7b8867baec3ec9060200160405180910390a2600486015460028401546001600160401b039081169116148015610d2a57506000835460ff166004811115610d2857610d28613823565b145b15610d9457825460ff191660011783556002830180546001600160401b034216600160401b026fffffffffffffffff0000000000000000199091161790556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b6001610dab83611aef565b6006811115610dbc57610dbc613823565b14610df3576040517fae9dcffd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dfd8282612cf1565b6000828152601260209081526040808320600180820154855260108452828520600b54845160e08101865292820154835260028201549583019590955260038101549382019390935260048301546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0820152909391926064916201000090910460ff1690610ea090612bdc565b610eaa9190613cc9565b610eb49190613cf6565b600b54909150600090606490610ed4906301000000900460ff1684613cc9565b610ede9190613cf6565b90508060136001016000828254610ef59190613d0a565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8b9190613d1d565b610f9757610f97613d3f565b81846003016000828254610fab9190613c96565b9091555050600b5460008781526006602052604090205461010090910460ff16906001600160401b03166001600160401b03161061082157610821866128cf565b6000610fff82610ffa612f08565b612f13565b92915050565b6000610fff82611013612f08565b612f27565b60008181526012602090815260408083206001810154845260109092528220600c546101009061105290600160801b900460ff1682613d55565b60018301546110659161ffff1690613cc9565b61056b9190613cf6565b336000908152600a602052604090206060906110919061108e90612fb9565b90565b905090565b61109e613762565b604080516101008082018352600b805460ff8082166080808701918252948304821660a080880191909152620100008404831660c08801526301000000909304821660e0870152855285519182018652600c80546001600160401b038082168552600160401b820416602085810191909152600160801b82048416988501989098527101000000000000000000000000000000000090049091166060830152600d805495969395938701949293919284019161115990613d70565b80601f016020809104026020016040519081016040528092919081815260200182805461118590613d70565b80156111d25780601f106111a7576101008083540402835291602001916111d2565b820191906000526020600020905b8154815290600101906020018083116111b557829003601f168201915b5050509190925250505081526040805160208181018352600385015460ff1682528301526004909201546001600160401b0316910152919050565b6112178133611bd0565b50565b3360009081526009602052604090206060906110919061108e90612fb9565b600061124c61124783613efe565b612fc6565b90503361125c6020840184614004565b6001600160a01b031614611283576040516334c69e3160e11b815260040160405180910390fd5b6000818152601060205260409020546001600160a01b0316156112d2576040517ffc7d069000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112e461014083016101208401614021565b6001600160401b0316158061132b575061130460e0830160c08401614021565b6001600160401b031661131f61014084016101208501614021565b6001600160401b031610155b15611362576040517fdf63f61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61137260a0830160808401614021565b6001600160401b03166000036113b4576040517f535ed2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113c460a0830160808401614021565b6001600160401b03166113de610100840160e08501614021565b6001600160401b0316111561141f576040517fb9551ab100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142f60e0830160c08401614021565b6001600160401b0316600003611471576040517f090a5ecd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208201356000036114af576040517f6aba7aae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608201356000036114ed576040517ffb7df0c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604082013560000361152b576040517f47ba51c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61153961010083018361403e565b611543908061405e565b905060000361157e576040517f86f8cf9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f546001600160401b031661159a60e0840160c08501614021565b6001600160401b031611156115db576040517f1267b3f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260106020526040902082906115f582826141f1565b50611608905060e0830160c08401614021565b6116129042613ca9565b600082815260116020526040902060020180546001600160401b0392909216600160801b0267ffffffffffffffff60801b1990921691909117905561165f61014083016101208401614021565b6116699042613ca9565b600082815260116020908152604090912060020180546001600160401b0393909316600160c01b0277ffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091556116ca906116c490840184614004565b82612ff6565b60006116dd6116d884613efe565b613018565b6000838152601160205260408120600101829055601380549293508392909190611708908490613d0a565b9091555061171890503382612bfb565b6000828152601160209081526040918290206002015491517f1bf9c457accf8703dbf7cdf1b58c2f74ddf2e525f98155c70b3d318d74609bd89261177292869290880191600160c01b90046001600160401b0316906143a3565b60405180910390a1505050565b806000808281526012602052604090205460ff1660068111156117a4576117a4613823565b036117c257604051638b41ec7f60e01b815260040160405180910390fd5b6117cd823333610696565b5050565b60008060006117e7846117e2612f08565b613054565b909250905081801561056b5750600254600160801b900460ff9081169116109392505050565b61189060405180604001604052806137cb6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b816000808281526012602052604090205460ff1660068111156118b5576118b5613823565b036118d357604051638b41ec7f60e01b815260040160405180910390fd5b600083815260126020526040902061196460405180604001604052806137cb6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b600180830154600090815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e08101865295830154865260028301548685015260038301548686015260048301546001600160401b038082166060890152600160401b820481166080890152600160801b8204811692880192909252600160c01b90041660c0860152918201939093528151808301835260058401805492949385019282908290611a1990613d70565b80601f0160208091040260200160405190810160405280929190818152602001828054611a4590613d70565b8015611a925780601f10611a6757610100808354040283529160200191611a92565b820191906000526020600020905b815481529060010190602001808311611a7557829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0390811683830152600890930154604090920191909152918352600290930154600160401b900490921691810191909152915050919050565b600081815260126020526040812060018101548203611b115750600092915050565b6000611b208260010154610573565b90506004825460ff166006811115611b3a57611b3a613823565b03611b49575060049392505050565b6002816004811115611b5d57611b5d613823565b03611b6c575060059392505050565b6003816004811115611b8057611b80613823565b03611b8f575060029392505050565b6004816004811115611ba357611ba3613823565b03611bb2575060039392505050565b505460ff1692915050565b6000610fff82611bcb612f08565b61310c565b60008281526010602052604090205482906001600160a01b0316611c0757604051635eeb253d60e11b815260040160405180910390fd5b6000838152601060209081526040808320601190925290912081546001600160a01b03163314611c4a576040516334c69e3160e11b815260040160405180910390fd5b6000611c5586610573565b90506002816004811115611c6b57611c6b613823565b14158015611c8b57506004816004811115611c8857611c88613823565b14155b8015611ca957506003816004811115611ca657611ca6613823565b14155b15611ce0576040517fc00b5b5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003611d1e576040517fbd8bdd9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002816004811115611d3257611d32613823565b03611dd057815460ff1916600217825560405186907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a2600086815260116020526040902060020154611d9a908790600160c01b90046001600160401b0316612bad565b6002830154611db291906001600160401b0316613cc9565b826001016000828254611dc59190613d0a565b90915550611f5d9050565b6004816004811115611de457611de4613823565b03611f51576040805160a0808201835285546001600160a01b03168252825160e08101845260018701548152600287015460208281019190915260038801548286015260048801546001600160401b038082166060850152600160401b820481166080850152600160801b8204811694840194909452600160c01b900490921660c08201529082015281518083018352600586018054611f4794889390850192909182908290611e9390613d70565b80601f0160208091040260200160405190810160405280929190818152602001828054611ebf90613d70565b8015611f0c5780601f10611ee157610100808354040283529160200191611f0c565b820191906000526020600020905b815481529060010190602001808311611eef57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b031690820152600890910154604090910152613018565b6001830155611f5d565b815460ff191660031782555b8254611f72906001600160a01b031687613143565b600182015460148054829190600090611f8c908490613d0a565b909155505060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612000573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120249190613d1d565b61204157604051637c2ccffd60e11b815260040160405180910390fd5b5050600060019091015550505050565b6000338161205f8585612b27565b905061206a81613165565b80156120935750600154600082815260208190526040902060ff9091169061209190612b81565b105b80156120b4575060008181526020819052604090206120b29083612b8b565b155b95945050505050565b6000828152601260209081526040808320600101548084526010909252909120546001600160a01b031661210457604051635eeb253d60e11b815260040160405180910390fd5b60008381526012602090815260408083206001810154845260108352818420825160038082526080820190945291949093909290820160608036833701905050905061215761215287610fec565b613192565b8160008151811061216a5761216a614443565b60209081029190910101526006820154612183906131a3565b8160018151811061219657612196614443565b6020026020010181815250508260020160089054906101000a90046001600160401b03166001600160401b0316816002815181106121d6576121d6614443565b6020026020010181815250506108218686836131af565b6122626040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b60008281526010602052604090205482906001600160a01b031661229957604051635eeb253d60e11b815260040160405180910390fd5b600083815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186526001840154815260028401548186015260038401548187015260048401546001600160401b038082166060840152600160401b820481166080840152600160801b8204811693830193909352600160c01b900490911660c0820152928101929092528251808401845260058201805493949293928501928290829061234d90613d70565b80601f016020809104026020016040519081016040528092919081815260200182805461237990613d70565b80156123c65780601f1061239b576101008083540402835291602001916123c6565b820191906000526020600020905b8154815290600101906020018083116123a957829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0316908201526008909101546040909101529392505050565b60008183106124125781612414565b825b9392505050565b60008481526010602052604090205484906001600160a01b031661245257604051635eeb253d60e11b815260040160405180910390fd5b600085815260116020908152604080832060108352818420815460ff19166003178255888552601290935292208154612494906001600160a01b031689613143565b60048101546124ac906001600160a01b0316886128ad565b60028101546000906124c8908a906001600160401b0316612bad565b60038301549091506124da8183613d0a565b601480546000906124ec908490613d0a565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612573573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125979190613d1d565b6125b457604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038881166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126479190613d1d565b610d9457604051637c2ccffd60e11b815260040160405180910390fd5b60008481526010602052604090205484906001600160a01b031661269b57604051635eeb253d60e11b815260040160405180910390fd5b600084815260126020526040902060048101546126c1906001600160a01b0316866128ad565b60028101546000906127079088906001600160401b0316612702826000908152601160205260409020600201546001600160401b03600160c01b9091041690565b61334d565b60038301549091506127198183613d0a565b6014805460009061272b908490613d0a565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156127b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d69190613d1d565b6127f357604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612862573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128869190613d1d565b6128a357604051637c2ccffd60e11b815260040160405180910390fd5b5050505050505050565b6001600160a01b0382166000908152600a602052604090206108f5908261342c565b600081815260126020908152604080832060018101548085526011909352922060028301546129089083906001600160401b0316612bad565b81600101600082825461291b9190613d0a565b90915550506004830154612938906001600160a01b0316856128ad565b600084815260208190526040812090818161295382826137d8565b5050845460ff1916600617855550506002808401805467ffffffffffffffff1916905560006003850181905560048501805473ffffffffffffffffffffffffffffffffffffffff191690559082018054600192906129bb9084906001600160401b0316614459565b82546101009290920a6001600160401b038181021990931691831602179091556002850154604051600160401b90910490911681528391507f33ba8f7627565d89f7ada2a6b81ea532b7aa9b11e91a78312d6e1fca0bfcd1dc9060200160405180910390a26000848152600660205260409020805467ffffffffffffffff19169055600082815260106020526040812060028301546004820154919291612a6e916001600160401b039081169116614459565b60048301546001600160401b039182169250600160c01b90041681118015612aab57506001835460ff166004811115612aa957612aa9613823565b145b1561082157825460ff19166004178355612ac6600142614459565b6002840180546001600160401b0392909216600160801b0267ffffffffffffffff60801b1990921691909117905560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a2505050505050565b60008282604051602001612b4e9291909182526001600160401b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b6000612414836001600160a01b038416613438565b6000610fff825490565b6001600160a01b03811660009081526001830160205260408120541515612414565b6000828152601160205260408120600201546124149084908490600160801b90046001600160401b031661334d565b600081608001516001600160401b03168260400151610fff9190613cc9565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd906064016020604051808303816000875af1158015612c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb29190613d1d565b6108f557604051637c2ccffd60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a602052604090206108f59082613487565b6000612cfc82613493565b6001600160401b03169050428110612d40576040517f6b4b1a4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600254612d5d90600160401b90046001600160401b031682613d0a565b4210612d95576040517fde55698e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602090815260408083206001600160401b038616845290915290205460ff1615612df1576040517efab7d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dfb838361310c565b612e31576040517fd3ffa66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038616845290915290205460ff1615612e8e576040517f98e7e55100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038087168552908352818420805460ff1916600190811790915587855260069093529083208054929390929091612edf91859116613ca9565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b6000611091426134a6565b6000612414612f228484612f27565b6134d2565b600080612f3661010043614479565b60025490915060009061010090612f659071010000000000000000000000000000000000900460ff168661448d565b612f6f91906144b8565b6001600160401b031690506000612f8861010087614479565b9050600061010082612f9a8587613d0a565b612fa49190613d0a565b612fae9190614479565b979650505050505050565b606060006124148361352c565b600081604051602001612fd99190613c6d565b604051602081830303815290604052805190602001209050919050565b6001600160a01b03821660009081526009602052604090206108f59082613487565b60006130278260200151613588565b602083015160a0810151606090910151613041919061448d565b6001600160401b0316610fff9190613cc9565b600080600061306285611aef565b60008681526005602052604081205491925090613087906001600160401b03166134a6565b9050600182600681111561309d5761309d613823565b1415806130b157506130af85826135a7565b155b156130c457600080935093505050613105565b6130ce8686612f27565b925060006130db846134d2565b905060006130e888611018565b90508015806130fe57506130fc8183614479565b155b9550505050505b9250929050565b600080600061311b8585613054565b90925090508180156120b45750600254600160801b900460ff90811691161015949350505050565b6001600160a01b03821660009081526009602052604090206108f5908261342c565b60008060008381526012602052604090205460ff16600681111561318b5761318b613823565b1492915050565b600060ff1982168161056b826135bd565b600080612414836135bd565b6000838152600760205260408120906131c6612f08565b6001600160401b0316815260208101919091526040016000205460ff161561321a576040517f3edef7db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546040517f94c8919d0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116916394c8919d916132649186918691016144de565b602060405180830381865afa158015613281573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a59190613d1d565b6132db576040517ffcd03a4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602052604081206001916132f4612f08565b6001600160401b031681526020808201929092526040908101600020805460ff19169315159390931790925590518481527f3b989d183b84b02259d7c14b34a9c9eb0fccb4c355a920d25e581e25aef4993d9101611772565b60008381526010602052604081206001600160401b03808416908516106133a0576040517f56607cb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600183015481526002830154602082015260038301549181019190915260048201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c082015261340f90613588565b6134198585614459565b6001600160401b03166120b49190613cc9565b6000612414838361362f565b600081815260018301602052604081205461347f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610fff565b506000610fff565b60006124148383613438565b6000610fff6134a183613729565b613736565b6000610fff7f000000000000000000000000000000000000000000000000000000000000000083614589565b60008060ff83166134e4600143613c96565b6134ee9190613c96565b409050600081900361350257613502613d3f565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561357c57602002820191906000526020600020905b815481526020019060010190808311613568575b50505050509050919050565b600081608001516001600160401b03168260200151610fff9190613cc9565b60006001600160401b0380841690831610612414565b7fff00000000000000000000000000000000000000000000000000000000000000811660015b602081101561069057600891821c916135fd908290613cc9565b83901b7fff000000000000000000000000000000000000000000000000000000000000001691909117906001016135e3565b60008181526001830160205260408120548015613718576000613653600183613c96565b855490915060009061366790600190613c96565b90508181146136cc57600086600001828154811061368757613687614443565b90600052602060002001549050808760000184815481106136aa576136aa614443565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806136dd576136dd6145af565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610fff565b6000915050610fff565b5092915050565b6000610fff826001613ca9565b6000610fff7f00000000000000000000000000000000000000000000000000000000000000008361448d565b60408051610100810182526000608080830182815260a080850184905260c0850184905260e08501849052908452845190810185528281526020808201849052818601849052606080830185905292820192909252818401528351908101845290815290918201905b8152600060209091015290565b508054600082559060005260206000209081019061121791905b8082111561380657600081556001016137f2565b5090565b60006020828403121561381c57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b602081016005831061384d5761384d613823565b91905290565b6001600160a01b038116811461121757600080fd5b60008060006060848603121561387d57600080fd5b83359250602084013561388f81613853565b9150604084013561389f81613853565b809150509250925092565b6001600160401b038116811461121757600080fd5b80356138ca816138aa565b919050565b600080604083850312156138e257600080fd5b8235915060208301356138f4816138aa565b809150509250929050565b6000610100828403121561069057600080fd5b6000806000610140848603121561392857600080fd5b83359250602084013561393a816138aa565b915061394985604086016138ff565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561398a5783518352928401929184019160010161396e565b50909695505050505050565b6000815180845260005b818110156139bc576020818501810151868301820152016139a0565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000825160ff8082511660208501528060208301511660408501528060408301511660608501528060608301511660808501526020850151915060e060a08501526001600160401b038083511661010086015280602084015116610120860152508060408301511661014085015280606083015116610160850152506080810151905060a0610180840152613a796101a0840182613996565b90506040840151613a9060c08501825160ff169052565b5060608401516001600160401b03811660e0850152509392505050565b600060208284031215613abf57600080fd5b81356001600160401b03811115613ad557600080fd5b8201610160818503121561241457600080fd5b6000815160408452613afd6040850182613996565b602093840151949093019390935250919050565b60006101606001600160a01b038351168452602083015180516020860152602081015160408601526040810151606086015260608101516001600160401b0380821660808801528060808401511660a08801528060a08401511660c08801528060c08401511660e0880152505050604083015181610100860152613b9782860182613ae8565b9150506060830151613bb56101208601826001600160401b03169052565b5060808301516101408501528091505092915050565b602081526000825160406020840152613be76060840182613b11565b90506001600160401b0360208501511660408401528091505092915050565b602081016007831061384d5761384d613823565b60008060408385031215613c2d57600080fd5b8235915060208301356138f481613853565b6000806101208385031215613c5357600080fd5b82359150613c6484602085016138ff565b90509250929050565b6020815260006124146020830184613b11565b634e487b7160e01b600052601160045260246000fd5b81810381811115610fff57610fff613c80565b6001600160401b0381811683821601908082111561372257613722613c80565b8082028115828204841417610fff57610fff613c80565b634e487b7160e01b600052601260045260246000fd5b600082613d0557613d05613ce0565b500490565b80820180821115610fff57610fff613c80565b600060208284031215613d2f57600080fd5b8151801515811461241457600080fd5b634e487b7160e01b600052600160045260246000fd5b61ffff82811682821603908082111561372257613722613c80565b600181811c90821680613d8457607f821691505b60208210810361069057634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613ddc57613ddc613da4565b60405290565b60405160a081016001600160401b0381118282101715613ddc57613ddc613da4565b60405160e081016001600160401b0381118282101715613ddc57613ddc613da4565b604051601f8201601f191681016001600160401b0381118282101715613e4e57613e4e613da4565b604052919050565b600060408284031215613e6857600080fd5b613e70613dba565b905081356001600160401b0380821115613e8957600080fd5b818401915084601f830112613e9d57600080fd5b8135602082821115613eb157613eb1613da4565b613ec3601f8301601f19168201613e26565b92508183528681838601011115613ed957600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b6000813603610160811215613f1257600080fd5b613f1a613de2565b8335613f2581613853565b815260e0601f1983011215613f3957600080fd5b613f41613e04565b91506020840135825260408401356020830152606084013560408301526080840135613f6c816138aa565b606083015260a0840135613f7f816138aa565b608083015260c0840135613f92816138aa565b60a083015260e0840135613fa5816138aa565b60c08301526020810191909152610100830135906001600160401b03821115613fcd57600080fd5b613fd936838601613e56565b6040820152613feb61012085016138bf565b6060820152610140939093013560808401525090919050565b60006020828403121561401657600080fd5b813561241481613853565b60006020828403121561403357600080fd5b8135612414816138aa565b60008235603e1983360301811261405457600080fd5b9190910192915050565b6000808335601e1984360301811261407557600080fd5b8301803591506001600160401b0382111561408f57600080fd5b60200191503681900382131561310557600080fd5b60008135610fff816138aa565b601f8211156108f5576000816000526020600020601f850160051c810160208610156140da5750805b601f850160051c820191505b81811015610821578281556001016140e6565b8135601e1983360301811261410d57600080fd5b820180356001600160401b0381111561412557600080fd5b6020813603818401131561413857600080fd5b61414c826141468654613d70565b866140b1565b6000601f831160018114614182576000841561416a57508482018301355b600019600386901b1c1916600185901b1786556141df565b600086815260209020601f19851690835b828110156141b4578785018601358255938501936001909101908501614193565b50858210156141d35760001960f88760031b161c198585890101351681555b505060018460011b0186555b50508085013560018501555050505050565b81356141fc81613853565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff1983541617825550602082013560018201556040820135600282015560608201356003820155600481016080830135614253816138aa565b815467ffffffffffffffff19166001600160401b0382161782555060a083013561427c816138aa565b81546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff0000000000000000161781556142f06142bb60c085016140a4565b825467ffffffffffffffff60801b191660809190911b77ffffffffffffffff0000000000000000000000000000000016178255565b6143486142ff60e085016140a4565b825477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff00000000000000000000000000000000000000000000000016178255565b5061436361435a61010084018461403e565b600583016140f9565b61439461437361012084016140a4565b600783016001600160401b0382166001600160401b03198254161781555050565b61014082013560088201555050565b60006101208201905084825283356020830152602084013560408301526040840135606083015260608401356143d8816138aa565b6001600160401b038082166080850152608086013591506143f8826138aa565b80821660a085015260a08601359150614410826138aa565b80821660c0850152505061442660c085016138bf565b6001600160401b0390811660e0840152831661010083015261056b565b634e487b7160e01b600052603260045260246000fd5b6001600160401b0382811682821603908082111561372257613722613c80565b60008261448857614488613ce0565b500690565b6001600160401b038181168382160280821691908281146144b0576144b0613c80565b505092915050565b60006001600160401b03808416806144d2576144d2613ce0565b92169190910692915050565b8235815260208084013590820152600061012082810161450e604085016040880180358252602090810135910152565b614528608085016080880180358252602090810135910152565b61454260c0850160c0880180358252602090810135910152565b61010084019190915283519081905261014083019060209081860160005b8281101561457c57815185529383019390830190600101614560565b5092979650505050505050565b60006001600160401b03808416806145a3576145a3613ce0565b92169190910492915050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122033c02c649d83b97f0723d0dc9a1fe47dba64816ebe09cb1c7a43424433129c0164736f6c63430008170033"; + public static string BYTECODE = "0x60c060405234801561001057600080fd5b50604051614eb5380380614eb583398101604081905261002f9161053b565b602083015180516040850151516001805460ff191660ff90921691909117905582906001600160401b03811660000361007b5760405163015536c760e51b815260040160405180910390fd5b6001600160401b031660805261010043116100a9576040516338f5f66160e11b815260040160405180910390fd5b8151600280546020850151604086015160608701516001600160401b039586166001600160801b0319909416939093176801000000000000000095909216949094021761ffff60801b1916600160801b60ff9485160260ff60881b191617600160881b9390911692909202919091178155608083015183919060039061012f90826106d9565b5050600480546001600160a01b0319166001600160a01b0393841617905550831660a05250825151606460ff909116111561017d576040516302bd816360e41b815260040160405180910390fd5b606483600001516040015160ff1611156101aa576040516354e5e0ab60e11b815260040160405180910390fd5b825160408101516020909101516064916101c391610797565b60ff1611156101e5576040516317ff9d0f60e21b815260040160405180910390fd5b82518051600b805460208085015160408087015160609788015160ff90811663010000000263ff0000001992821662010000029290921663ffff0000199482166101000261ffff1990971698821698909817959095179290921695909517178355808801518051600c80549383015196830151978301518516600160881b0260ff60881b1998909516600160801b029790971661ffff60801b196001600160401b0397881668010000000000000000026001600160801b031990951697909216969096179290921791909116939093171783556080820151869391929190600d906102d090826106d9565b50505060408201515160038201805460ff191660ff909216919091179055606090910151600490910180546001600160401b0319166001600160401b03909216919091179055506107c8915050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156103575761035761031f565b60405290565b604051608081016001600160401b03811182821017156103575761035761031f565b604051601f8201601f191681016001600160401b03811182821017156103a7576103a761031f565b604052919050565b805160ff811681146103c057600080fd5b919050565b80516001600160401b03811681146103c057600080fd5b600060a082840312156103ee57600080fd5b6103f6610335565b9050610401826103c5565b815261040f602083016103c5565b6020820152610420604083016103af565b6040820152610431606083016103af565b606082015260808201516001600160401b0381111561044f57600080fd5b8201601f8101841361046057600080fd5b80516001600160401b038111156104795761047961031f565b61048c601f8201601f191660200161037f565b8181528560208385010111156104a157600080fd5b60005b828110156104c0576020818501810151838301820152016104a4565b5060006020838301015280608085015250505092915050565b6000602082840312156104eb57600080fd5b604051602081016001600160401b038111828210171561050d5761050d61031f565b60405290508061051c836103af565b905292915050565b80516001600160a01b03811681146103c057600080fd5b60008060006060848603121561055057600080fd5b83516001600160401b0381111561056657600080fd5b840180860360e081121561057957600080fd5b61058161035d565b608082121561058f57600080fd5b61059761035d565b91506105a2836103af565b82526105b0602084016103af565b60208301526105c1604084016103af565b60408301526105d2606084016103af565b60608301529081526080820151906001600160401b038211156105f457600080fd5b610600888385016103dc565b60208201526106128860a085016104d9565b604082015261062360c084016103c5565b6060820152945061063991505060208501610524565b915061064760408501610524565b90509250925092565b600181811c9082168061066457607f821691505b60208210810361068457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156106d457806000526020600020601f840160051c810160208510156106b15750805b601f840160051c820191505b818110156106d157600081556001016106bd565b50505b505050565b81516001600160401b038111156106f2576106f261031f565b610706816107008454610650565b8461068a565b6020601f82116001811461073a57600083156107225750848201515b600019600385901b1c1916600184901b1784556106d1565b600084815260208120601f198516915b8281101561076a578785015182556020948501946001909201910161074a565b50848210156107885786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60ff81811683821602908116908181146107c157634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a051614690610825600039600081816104bf01528181610f640152818161200d0152818161257e0152818161262e015281816127bd0152818161286d0152612c97015260008181613501015261379101526146906000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80636e2b54ee116100f9578063c0cc4add11610097578063e8aa0a0711610071578063e8aa0a0714610461578063f752196b14610474578063fb1e61ca1461049d578063fc0c546a146104bd57600080fd5b8063c0cc4add14610428578063c5d433511461043b578063d02bbe331461044e57600080fd5b8063a29c29a4116100d3578063a29c29a4146103b2578063a3a0807e146103c5578063b396dc79146103e8578063be5cdc481461040857600080fd5b80636e2b54ee146103845780639777b72c1461039757806399b6da0c1461039f57600080fd5b8063329b5a0b1161016657806351a766421161014057806351a76642146103035780635da73835146103165780636b00c8cf1461032b5780636c70bee91461036f57600080fd5b8063329b5a0b14610298578063458d2bf1146102cb5780634641dce6146102de57600080fd5b806312827602116101a2578063128276021461022e5780631d873c1b14610241578063237d84821461025457806326d6f8341461026757600080fd5b806302fa8e65146101c957806305b90773146101f95780630aefaabe14610219575b600080fd5b6101dc6101d736600461385e565b6104e3565b6040516001600160401b0390911681526020015b60405180910390f35b61020c61020736600461385e565b6105c1565b6040516101f0919061388d565b61022c6102273660046138bc565b6106e4565b005b61022c61023c366004613923565b610877565b61022c61024f366004613966565b610948565b61022c610262366004613923565b610dee565b61028a61027536600461385e565b60009081526012602052604090206003015490565b6040519081526020016101f0565b6101dc6102a636600461385e565b600090815260116020526040902060020154600160c01b90046001600160401b031690565b61028a6102d936600461385e565b61103a565b6102f16102ec36600461385e565b611053565b60405160ff90911681526020016101f0565b61028a61031136600461385e565b611066565b61031e6110c5565b6040516101f091906139a6565b61035761033936600461385e565b6000908152601260205260409020600401546001600160a01b031690565b6040516001600160a01b0390911681526020016101f0565b6103776110ec565b6040516101f09190613a84565b61022c61039236600461385e565b611263565b61031e611270565b61022c6103ad366004613b0c565b61128f565b61022c6103c036600461385e565b6117d5565b6103d86103d336600461385e565b611827565b60405190151581526020016101f0565b6103fb6103f636600461385e565b611863565b6040516101f09190613c3b565b61041b61041636600461385e565b611b45565b6040516101f09190613c76565b6103d861043636600461385e565b611c13565b61022c610449366004613c8a565b611c26565b6103d861045c366004613923565b6120a7565b61022c61046f366004613caf565b612113565b6101dc61048236600461385e565b6000908152600660205260409020546001600160401b031690565b6104b06104ab36600461385e565b612243565b6040516101f09190613cdd565b7f0000000000000000000000000000000000000000000000000000000000000000610357565b6000806104ef836105c1565b9050600081600481111561050557610505613877565b14806105225750600181600481111561052057610520613877565b145b1561054e575050600090815260116020526040902060020154600160801b90046001600160401b031690565b600281600481111561056257610562613877565b0361058e575050600090815260116020526040902060020154600160c01b90046001600160401b031690565b6000838152601160205260409020600201546105ba90600160801b90046001600160401b031642612459565b9392505050565b60008181526010602052604081205482906001600160a01b03166105f857604051635eeb253d60e11b815260040160405180910390fd5b600083815260116020526040812090815460ff16600481111561061d5761061d613877565b14801561065c5750600084815260116020526040902060020154600160c01b90046001600160401b03166001600160401b0316426001600160401b0316115b1561066b5760029250506106de565b6001815460ff16600481111561068357610683613877565b14806106a457506000815460ff1660048111156106a2576106a2613877565b145b80156106c8575060028101546001600160401b03600160801b909104811642909116115b156106d75760039250506106de565b5460ff1691505b50919050565b826000808281526012602052604090205460ff16600681111561070957610709613877565b0361072757604051638b41ec7f60e01b815260040160405180910390fd5b600084815260126020526040902060048101546001600160a01b0316331461077b576040517f57a6f4e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061078686611b45565b9050600481600681111561079c5761079c613877565b036107d3576040517fc2cbf77700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028160068111156107e7576107e7613877565b03610801576107fc826001015487878761246f565b61086f565b600581600681111561081557610815613877565b0361082a576107fc82600101548787876126b8565b600381600681111561083e5761083e613877565b0361084d576107fc3387612901565b600181600681111561086157610861613877565b0361086f5761086f86612923565b505050505050565b61088182826120a7565b6108b7576040517f424a04ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108c38383612b7b565b60008181526020819052604090209091506108de9033612bc0565b50600154600082815260208190526040902060ff909116906108ff90612bd5565b03610943576040516001600160401b038316815283907fc8e6c955744189a19222ec226b72ac1435d88d5745252dac56e6f679f64c037a9060200160405180910390a25b505050565b60008381526010602052604090205483906001600160a01b031661097f57604051635eeb253d60e11b815260040160405180910390fd5b600084815260106020526040902060048101546001600160401b03908116908516106109d7576040517f3b920b8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109e38686612b7b565b60008181526020819052604090209091506109fe9033612bdf565b610a34576040517fd651ce1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152601260209081526040808320600181018a90556002810180546fffffffffffffffff00000000000000001916600160401b6001600160401b038c1602179055898452601190925282209091610a8d84611b45565b6006811115610a9e57610a9e613877565b14158015610ac657506006610ab284611b45565b6006811115610ac357610ac3613877565b14155b15610afd576040517fff556acf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600560205260409020805467ffffffffffffffff1916426001600160401b0316179055610b2f8387612113565b60048201805473ffffffffffffffffffffffffffffffffffffffff191633179055600280830180546001600160401b0342811667ffffffffffffffff19909216919091179091559082018054600192600091610b8d91859116613d06565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610bd2888360020160009054906101000a90046001600160401b0316612c01565b816001016000828254610be59190613d25565b90915550506040805160e081018252600186015481526002860154602082015260038601549181019190915260048501546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c08201526000908190610c5e90612c30565b90506006610c6b86611b45565b6006811115610c7c57610c7c613877565b03610caf57600b54606490610c949060ff1683613d38565b610c9e9190613d65565b610ca89082613d25565b9150610cb3565b8091505b610cbd3383612c4f565b8160136000016000828254610cd29190613d79565b9091555050600384018190556004840154610cf6906001600160a01b031686612d23565b835460ff191660011784556040516001600160401b038a1681528a907f8f301470a994578b52323d625dfbf827ca5208c81747d3459be7b8867baec3ec9060200160405180910390a2600486015460028401546001600160401b039081169116148015610d7857506000835460ff166004811115610d7657610d76613877565b145b15610de257825460ff191660011783556002830180546001600160401b034216600160401b026fffffffffffffffff0000000000000000199091161790556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b6001610df983611b45565b6006811115610e0a57610e0a613877565b14610e41576040517fae9dcffd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4b8282612d45565b6000828152601260209081526040808320600180820154855260108452828520600b54845160e08101865292820154835260028201549583019590955260038101549382019390935260048301546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0820152909391926064916201000090910460ff1690610eee90612c30565b610ef89190613d38565b610f029190613d65565b600b54909150600090606490610f22906301000000900460ff1684613d38565b610f2c9190613d65565b90508060136001016000828254610f439190613d79565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd99190613d8c565b610fe557610fe5613dae565b81846003016000828254610ff99190613d25565b9091555050600b5460008781526006602052604090205461010090910460ff16906001600160401b03166001600160401b03161061086f5761086f86612923565b600061104d82611048612f5c565b612f67565b92915050565b600061104d82611061612f5c565b612f7b565b60008181526012602090815260408083206001810154845260109092528220600c54610100906110a090600160801b900460ff1682613dc4565b60018301546110b39161ffff1690613d38565b6110bd9190613d65565b949350505050565b336000908152600a602052604090206060906110e7906110e49061300d565b90565b905090565b6110f46137b6565b604080516101008082018352600b805460ff8082166080808701918252948304821660a080880191909152620100008404831660c08801526301000000909304821660e0870152855285519182018652600c80546001600160401b038082168552600160401b820416602085810191909152600160801b82048416988501989098527101000000000000000000000000000000000090049091166060830152600d80549596939593870194929391928401916111af90613dde565b80601f01602080910402602001604051908101604052809291908181526020018280546111db90613dde565b80156112285780601f106111fd57610100808354040283529160200191611228565b820191906000526020600020905b81548152906001019060200180831161120b57829003601f168201915b5050509190925250505081526040805160208181018352600385015460ff1682528301526004909201546001600160401b0316910152919050565b61126d8133611c26565b50565b3360009081526009602052604090206060906110e7906110e49061300d565b60006112a261129d83613f6f565b61301a565b9050336112b26020840184614078565b6001600160a01b0316146112d9576040516334c69e3160e11b815260040160405180910390fd5b6000818152601060205260409020546001600160a01b031615611328576040517ffc7d069000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133a61014083016101208401614095565b6001600160401b03161580611381575061135a60e0830160c08401614095565b6001600160401b031661137561014084016101208501614095565b6001600160401b031610155b156113b8576040517fdf63f61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113c860a0830160808401614095565b6001600160401b031660000361140a576040517f535ed2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61141a60a0830160808401614095565b6001600160401b0316611434610100840160e08501614095565b6001600160401b03161115611475576040517fb9551ab100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61148560e0830160c08401614095565b6001600160401b03166000036114c7576040517f090a5ecd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020820135600003611505576040517f6aba7aae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060820135600003611543576040517ffb7df0c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040820135600003611581576040517f47ba51c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61158f6101008301836140b2565b61159990806140d2565b90506000036115d4576040517f86f8cf9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f546001600160401b03166115f060e0840160c08501614095565b6001600160401b03161115611631576040517f1267b3f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152601060205260409020829061164b8282614272565b5061165e905060e0830160c08401614095565b6116689042613d06565b600082815260116020526040902060020180546001600160401b0392909216600160801b0267ffffffffffffffff60801b199092169190911790556116b561014083016101208401614095565b6116bf9042613d06565b600082815260116020908152604090912060020180546001600160401b0393909316600160c01b0277ffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091556117209061171a90840184614078565b8261304a565b600061173361172e84613f6f565b61306c565b600083815260116020526040812060010182905560138054929350839290919061175e908490613d79565b9091555061176e90503382612c4f565b6000828152601160209081526040918290206002015491517f1bf9c457accf8703dbf7cdf1b58c2f74ddf2e525f98155c70b3d318d74609bd8926117c892869290880191600160c01b90046001600160401b031690614426565b60405180910390a1505050565b806000808281526012602052604090205460ff1660068111156117fa576117fa613877565b0361181857604051638b41ec7f60e01b815260040160405180910390fd5b6118238233336106e4565b5050565b600080600061183d84611838612f5c565b6130a8565b90925090508180156110bd5750600254600160801b900460ff9081169116109392505050565b6118e6604051806040016040528061381f6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b816000808281526012602052604090205460ff16600681111561190b5761190b613877565b0361192957604051638b41ec7f60e01b815260040160405180910390fd5b60008381526012602052604090206119ba604051806040016040528061381f6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b600180830154600090815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e08101865295830154865260028301548685015260038301548686015260048301546001600160401b038082166060890152600160401b820481166080890152600160801b8204811692880192909252600160c01b90041660c0860152918201939093528151808301835260058401805492949385019282908290611a6f90613dde565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9b90613dde565b8015611ae85780601f10611abd57610100808354040283529160200191611ae8565b820191906000526020600020905b815481529060010190602001808311611acb57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0390811683830152600890930154604090920191909152918352600290930154600160401b900490921691810191909152915050919050565b600081815260126020526040812060018101548203611b675750600092915050565b6000611b7682600101546105c1565b90506004825460ff166006811115611b9057611b90613877565b03611b9f575060049392505050565b6002816004811115611bb357611bb3613877565b03611bc2575060059392505050565b6003816004811115611bd657611bd6613877565b03611be5575060029392505050565b6004816004811115611bf957611bf9613877565b03611c08575060039392505050565b505460ff1692915050565b600061104d82611c21612f5c565b613160565b60008281526010602052604090205482906001600160a01b0316611c5d57604051635eeb253d60e11b815260040160405180910390fd5b6000838152601060209081526040808320601190925290912081546001600160a01b03163314611ca0576040516334c69e3160e11b815260040160405180910390fd5b6000611cab866105c1565b90506002816004811115611cc157611cc1613877565b14158015611ce157506004816004811115611cde57611cde613877565b14155b8015611cff57506003816004811115611cfc57611cfc613877565b14155b15611d36576040517fc00b5b5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003611d74576040517fbd8bdd9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002816004811115611d8857611d88613877565b03611e2657815460ff1916600217825560405186907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a2600086815260116020526040902060020154611df0908790600160c01b90046001600160401b0316612c01565b6002830154611e0891906001600160401b0316613d38565b826001016000828254611e1b9190613d79565b90915550611fb39050565b6004816004811115611e3a57611e3a613877565b03611fa7576040805160a0808201835285546001600160a01b03168252825160e08101845260018701548152600287015460208281019190915260038801548286015260048801546001600160401b038082166060850152600160401b820481166080850152600160801b8204811694840194909452600160c01b900490921660c08201529082015281518083018352600586018054611f9d94889390850192909182908290611ee990613dde565b80601f0160208091040260200160405190810160405280929190818152602001828054611f1590613dde565b8015611f625780601f10611f3757610100808354040283529160200191611f62565b820191906000526020600020905b815481529060010190602001808311611f4557829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b03169082015260089091015460409091015261306c565b6001830155611fb3565b815460ff191660031782555b8254611fc8906001600160a01b031687613197565b600182015460148054829190600090611fe2908490613d79565b909155505060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612056573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207a9190613d8c565b61209757604051637c2ccffd60e11b815260040160405180910390fd5b5050600060019091015550505050565b600033816120b58585612b7b565b90506120c0816131b9565b80156120e95750600154600082815260208190526040902060ff909116906120e790612bd5565b105b801561210a575060008181526020819052604090206121089083612bdf565b155b95945050505050565b6000828152601260209081526040808320600101548084526010909252909120546001600160a01b031661215a57604051635eeb253d60e11b815260040160405180910390fd5b6000838152601260209081526040808320600181015484526010835281842082516003808252608082019094529194909390929082016060803683370190505090506121ad6121a88761103a565b6131e6565b816000815181106121c0576121c06144d3565b602090810291909101015260068201546121d9906131f7565b816001815181106121ec576121ec6144d3565b6020026020010181815250508260020160089054906101000a90046001600160401b03166001600160401b03168160028151811061222c5761222c6144d3565b60200260200101818152505061086f868683613203565b6122b86040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b60008281526010602052604090205482906001600160a01b03166122ef57604051635eeb253d60e11b815260040160405180910390fd5b600083815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186526001840154815260028401548186015260038401548187015260048401546001600160401b038082166060840152600160401b820481166080840152600160801b8204811693830193909352600160c01b900490911660c082015292810192909252825180840184526005820180549394929392850192829082906123a390613dde565b80601f01602080910402602001604051908101604052809291908181526020018280546123cf90613dde565b801561241c5780601f106123f15761010080835404028352916020019161241c565b820191906000526020600020905b8154815290600101906020018083116123ff57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0316908201526008909101546040909101529392505050565b600081831061246857816105ba565b5090919050565b60008481526010602052604090205484906001600160a01b03166124a657604051635eeb253d60e11b815260040160405180910390fd5b600085815260116020908152604080832060108352818420815460ff191660031782558885526012909352922081546124e8906001600160a01b031689613197565b6004810154612500906001600160a01b031688612901565b600281015460009061251c908a906001600160401b0316612c01565b600383015490915061252e8183613d79565b60148054600090612540908490613d79565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156125c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125eb9190613d8c565b61260857604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038881166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269b9190613d8c565b610de257604051637c2ccffd60e11b815260040160405180910390fd5b60008481526010602052604090205484906001600160a01b03166126ef57604051635eeb253d60e11b815260040160405180910390fd5b60008481526012602052604090206004810154612715906001600160a01b031686612901565b600281015460009061275b9088906001600160401b0316612756826000908152601160205260409020600201546001600160401b03600160c01b9091041690565b6133a1565b600383015490915061276d8183613d79565b6014805460009061277f908490613d79565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282a9190613d8c565b61284757604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156128b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128da9190613d8c565b6128f757604051637c2ccffd60e11b815260040160405180910390fd5b5050505050505050565b6001600160a01b0382166000908152600a602052604090206109439082613480565b6000818152601260209081526040808320600181015480855260119093529220600283015461295c9083906001600160401b0316612c01565b81600101600082825461296f9190613d79565b9091555050600483015461298c906001600160a01b031685612901565b60008481526020819052604081209081816129a7828261382c565b5050845460ff1916600617855550506002808401805467ffffffffffffffff1916905560006003850181905560048501805473ffffffffffffffffffffffffffffffffffffffff19169055908201805460019290612a0f9084906001600160401b03166144e9565b82546101009290920a6001600160401b038181021990931691831602179091556002850154604051600160401b90910490911681528391507f33ba8f7627565d89f7ada2a6b81ea532b7aa9b11e91a78312d6e1fca0bfcd1dc9060200160405180910390a26000848152600660205260409020805467ffffffffffffffff19169055600082815260106020526040812060028301546004820154919291612ac2916001600160401b0390811691166144e9565b60048301546001600160401b039182169250600160c01b90041681118015612aff57506001835460ff166004811115612afd57612afd613877565b145b1561086f57825460ff19166004178355612b1a6001426144e9565b6002840180546001600160401b0392909216600160801b0267ffffffffffffffff60801b1990921691909117905560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a2505050505050565b60008282604051602001612ba29291909182526001600160401b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b60006105ba836001600160a01b03841661348c565b600061104d825490565b6001600160a01b038116600090815260018301602052604081205415156105ba565b6000828152601160205260408120600201546105ba9084908490600160801b90046001600160401b03166133a1565b600081608001516001600160401b0316826040015161104d9190613d38565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd906064016020604051808303816000875af1158015612ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d069190613d8c565b61094357604051637c2ccffd60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a6020526040902061094390826134db565b6000612d50826134e7565b6001600160401b03169050428110612d94576040517f6b4b1a4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600254612db190600160401b90046001600160401b031682613d79565b4210612de9576040517fde55698e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602090815260408083206001600160401b038616845290915290205460ff1615612e45576040517efab7d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e4f8383613160565b612e85576040517fd3ffa66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038616845290915290205460ff1615612ee2576040517f98e7e55100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038087168552908352818420805460ff1916600190811790915587855260069093529083208054929390929091612f3391859116613d06565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b60006110e7426134fa565b60006105ba612f768484612f7b565b613526565b600080612f8a61010043614508565b60025490915060009061010090612fb99071010000000000000000000000000000000000900460ff168661451c565b612fc3919061453e565b6001600160401b031690506000612fdc61010087614508565b9050600061010082612fee8587613d79565b612ff89190613d79565b6130029190614508565b979650505050505050565b606060006105ba83613580565b60008160405160200161302d9190613cdd565b604051602081830303815290604052805190602001209050919050565b6001600160a01b038216600090815260096020526040902061094390826134db565b600061307b82602001516135dc565b602083015160a0810151606090910151613095919061451c565b6001600160401b031661104d9190613d38565b60008060006130b685611b45565b600086815260056020526040812054919250906130db906001600160401b03166134fa565b905060018260068111156130f1576130f1613877565b141580613105575061310385826135fb565b155b1561311857600080935093505050613159565b6131228686612f7b565b9250600061312f84613526565b9050600061313c88611066565b905080158061315257506131508183614508565b155b9550505050505b9250929050565b600080600061316f85856130a8565b909250905081801561210a5750600254600160801b900460ff90811691161015949350505050565b6001600160a01b03821660009081526009602052604090206109439082613480565b60008060008381526012602052604090205460ff1660068111156131df576131df613877565b1492915050565b600060ff198216816110bd82613611565b6000806105ba83613611565b60008381526007602052604081209061321a612f5c565b6001600160401b0316815260208101919091526040016000205460ff161561326e576040517f3edef7db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546040517f94c8919d0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116916394c8919d916132b891869186910161456c565b602060405180830381865afa1580156132d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f99190613d8c565b61332f576040517ffcd03a4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260408120600191613348612f5c565b6001600160401b031681526020808201929092526040908101600020805460ff19169315159390931790925590518481527f3b989d183b84b02259d7c14b34a9c9eb0fccb4c355a920d25e581e25aef4993d91016117c8565b60008381526010602052604081206001600160401b03808416908516106133f4576040517f56607cb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600183015481526002830154602082015260038301549181019190915260048201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0820152613463906135dc565b61346d85856144e9565b6001600160401b031661210a9190613d38565b60006105ba8383613683565b60008181526001830160205260408120546134d35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561104d565b50600061104d565b60006105ba838361348c565b600061104d6134f58361377d565b61378a565b600061104d7f000000000000000000000000000000000000000000000000000000000000000083614616565b60008060ff8316613538600143613d25565b6135429190613d25565b409050600081900361355657613556613dae565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156135d057602002820191906000526020600020905b8154815260200190600101908083116135bc575b50505050509050919050565b600081608001516001600160401b0316826020015161104d9190613d38565b60006001600160401b03808416908316106105ba565b7fff00000000000000000000000000000000000000000000000000000000000000811660015b60208110156106de57600891821c91613651908290613d38565b83901b7fff00000000000000000000000000000000000000000000000000000000000000169190911790600101613637565b6000818152600183016020526040812054801561376c5760006136a7600183613d25565b85549091506000906136bb90600190613d25565b90508181146137205760008660000182815481106136db576136db6144d3565b90600052602060002001549050808760000184815481106136fe576136fe6144d3565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061373157613731614644565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061104d565b600091505061104d565b5092915050565b600061104d826001613d06565b600061104d7f00000000000000000000000000000000000000000000000000000000000000008361451c565b60408051610100810182526000608080830182815260a080850184905260c0850184905260e08501849052908452845190810185528281526020808201849052818601849052606080830185905292820192909252818401528351908101845290815290918201905b8152600060209091015290565b508054600082559060005260206000209081019061126d91905b8082111561385a5760008155600101613846565b5090565b60006020828403121561387057600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60208101600583106138a1576138a1613877565b91905290565b6001600160a01b038116811461126d57600080fd5b6000806000606084860312156138d157600080fd5b8335925060208401356138e3816138a7565b915060408401356138f3816138a7565b809150509250925092565b6001600160401b038116811461126d57600080fd5b803561391e816138fe565b919050565b6000806040838503121561393657600080fd5b823591506020830135613948816138fe565b809150509250929050565b600061010082840312156106de57600080fd5b6000806000610140848603121561397c57600080fd5b83359250602084013561398e816138fe565b915061399d8560408601613953565b90509250925092565b602080825282518282018190526000918401906040840190835b818110156139de5783518352602093840193909201916001016139c0565b509095945050505050565b6000815180845260005b81811015613a0f576020818501810151868301820152016139f3565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160401b0381511682526001600160401b03602082015116602083015260ff604082015116604083015260ff60608201511660608301526000608082015160a060808501526110bd60a08501826139e9565b602081526000825160ff815116602084015260ff602082015116604084015260ff604082015116606084015260ff606082015116608084015250602083015160e060a0840152613ad8610100840182613a2f565b90506040840151613aef60c08501825160ff169052565b5060608401516001600160401b03811660e0850152509392505050565b600060208284031215613b1e57600080fd5b81356001600160401b03811115613b3457600080fd5b820161016081850312156105ba57600080fd5b6000815160408452613b5c60408501826139e9565b602093840151949093019390935250919050565b6001600160a01b038151168252600060208201518051602085015260208101516040850152604081015160608501526001600160401b0360608201511660808501526001600160401b0360808201511660a08501526001600160401b0360a08201511660c08501526001600160401b0360c08201511660e0850152506040820151610160610100850152613c08610160850182613b47565b90506060830151613c256101208601826001600160401b03169052565b5060808301516101408501528091505092915050565b602081526000825160406020840152613c576060840182613b70565b90506001600160401b0360208501511660408401528091505092915050565b60208101600783106138a1576138a1613877565b60008060408385031215613c9d57600080fd5b823591506020830135613948816138a7565b6000806101208385031215613cc357600080fd5b82359150613cd48460208501613953565b90509250929050565b6020815260006105ba6020830184613b70565b634e487b7160e01b600052601160045260246000fd5b6001600160401b03818116838216019081111561104d5761104d613cf0565b8181038181111561104d5761104d613cf0565b808202811582820484141761104d5761104d613cf0565b634e487b7160e01b600052601260045260246000fd5b600082613d7457613d74613d4f565b500490565b8082018082111561104d5761104d613cf0565b600060208284031215613d9e57600080fd5b815180151581146105ba57600080fd5b634e487b7160e01b600052600160045260246000fd5b61ffff828116828216039081111561104d5761104d613cf0565b600181811c90821680613df257607f821691505b6020821081036106de57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613e4a57613e4a613e12565b60405290565b60405160a081016001600160401b0381118282101715613e4a57613e4a613e12565b60405160e081016001600160401b0381118282101715613e4a57613e4a613e12565b604051601f8201601f191681016001600160401b0381118282101715613ebc57613ebc613e12565b604052919050565b600060408284031215613ed657600080fd5b613ede613e28565b905081356001600160401b03811115613ef657600080fd5b8201601f81018413613f0757600080fd5b80356001600160401b03811115613f2057613f20613e12565b613f33601f8201601f1916602001613e94565b818152856020838501011115613f4857600080fd5b81602084016020830137600060209282018301528352928301359282019290925292915050565b6000813603610160811215613f8357600080fd5b613f8b613e50565b8335613f96816138a7565b815260e0601f1983011215613faa57600080fd5b613fb2613e72565b60208581013582526040808701359183019190915260608601359082015291506080840135613fe0816138fe565b606083015260a0840135613ff3816138fe565b608083015260c0840135614006816138fe565b60a083015260e0840135614019816138fe565b60c08301526020810191909152610100830135906001600160401b0382111561404157600080fd5b61404d36838601613ec4565b604082015261405f6101208501613913565b6060820152610140939093013560808401525090919050565b60006020828403121561408a57600080fd5b81356105ba816138a7565b6000602082840312156140a757600080fd5b81356105ba816138fe565b60008235603e198336030181126140c857600080fd5b9190910192915050565b6000808335601e198436030181126140e957600080fd5b8301803591506001600160401b0382111561410357600080fd5b60200191503681900382131561315957600080fd5b6000813561104d816138fe565b601f82111561094357806000526020600020601f840160051c8101602085101561414c5750805b601f840160051c820191505b8181101561416c5760008155600101614158565b5050505050565b8135601e1983360301811261418757600080fd5b820180356001600160401b03811180156141a057600080fd5b8136036020840113156141b257600080fd5b600090506141ca826141c48654613dde565b86614125565b80601f8311600181146141ff578284156141e75750848201602001355b600019600386901b1c1916600185901b17865561425e565b600086815260209020601f19851690845b8281101561423257602085890181013583559485019460019092019101614210565b50858210156142525760001960f88760031b161c19602085890101351681555b505060018460011b0186555b505050505060209190910135600190910155565b813561427d816138a7565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03919091161781556020820135600182015560408201356002820155606082013560038201556004810160808301356142d5816138fe565b815467ffffffffffffffff19166001600160401b0382161782555060a08301356142fe816138fe565b81546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff00000000000000001617815561437261433d60c08501614118565b825467ffffffffffffffff60801b191660809190911b77ffffffffffffffff0000000000000000000000000000000016178255565b6143ca61438160e08501614118565b825477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff00000000000000000000000000000000000000000000000016178255565b506143e56143dc6101008401846140b2565b60058301614173565b6144166143f56101208401614118565b600783016001600160401b0382166001600160401b03198254161781555050565b6101409190910135600890910155565b838152823560208083019190915283013560408083019190915283013560608083019190915261012082019084013561445e816138fe565b6001600160401b038116608084015250608084013561447c816138fe565b6001600160401b03811660a08401525060a084013561449a816138fe565b6001600160401b03811660c0840152506144b660c08501613913565b6001600160401b0390811660e084015283166101008301526110bd565b634e487b7160e01b600052603260045260246000fd5b6001600160401b03828116828216039081111561104d5761104d613cf0565b60008261451757614517613d4f565b500690565b6001600160401b03818116838216029081169081811461377657613776613cf0565b60006001600160401b0383168061455757614557613d4f565b806001600160401b0384160691505092915050565b82358152602080840135908201526000610120820161459b604084016040870180358252602090810135910152565b6145b5608084016080870180358252602090810135910152565b6145cf60c0840160c0870180358252602090810135910152565b610120610100840152835190819052602084019061014084019060005b8181101561460a5783518352602093840193909201916001016145ec565b50909695505050505050565b60006001600160401b0383168061462f5761462f613d4f565b806001600160401b0384160491505092915050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122022d1585d4a2549e539759684fb5042b4c2cc27b217dc5dff9d79f66b7f62b36964736f6c634300081c0033"; public MarketplaceDeploymentBase() : base(BYTECODE) { } public MarketplaceDeploymentBase(string byteCode) : base(byteCode) { } [Parameter("tuple", "config", 1)] diff --git a/ProjectPlugins/GethPlugin/GethNode.cs b/ProjectPlugins/GethPlugin/GethNode.cs index 2866f285..26bf1f03 100644 --- a/ProjectPlugins/GethPlugin/GethNode.cs +++ b/ProjectPlugins/GethPlugin/GethNode.cs @@ -20,6 +20,8 @@ namespace GethPlugin string SendEth(IHasEthAddress account, Ether eth); string SendEth(EthAddress account, Ether eth); TResult Call(string contractAddress, TFunction function) where TFunction : FunctionMessage, new(); + TResult Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new(); + void Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new(); string SendTransaction(string contractAddress, TFunction function) where TFunction : FunctionMessage, new(); Transaction GetTransaction(string transactionHash); decimal? GetSyncedBlockNumber(); @@ -131,6 +133,16 @@ namespace GethPlugin return StartInteraction().Call(contractAddress, function); } + public TResult Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new() + { + return StartInteraction().Call(contractAddress, function, blockNumber); + } + + public void Call(string contractAddress, TFunction function, ulong blockNumber) where TFunction : FunctionMessage, new() + { + StartInteraction().Call(contractAddress, function, blockNumber); + } + public string SendTransaction(string contractAddress, TFunction function) where TFunction : FunctionMessage, new() { return StartInteraction().SendTransaction(contractAddress, function); diff --git a/Tools/TestNetRewarder/EventsFormatter.cs b/Tools/TestNetRewarder/EventsFormatter.cs index 041438bd..1766620e 100644 --- a/Tools/TestNetRewarder/EventsFormatter.cs +++ b/Tools/TestNetRewarder/EventsFormatter.cs @@ -102,6 +102,28 @@ namespace TestNetRewarder errors.Add(msg); } + public void ProcessPeriodReports(PeriodReport[] periodReports) + { + var lines = periodReports.Select(FormatPeriodReport).ToList(); + lines.Insert(0, FormatPeriodReportLine("period", "totalSlots", "required", "missed")); + AddBlock(0, "Proof system report", lines.ToArray()); + } + + private string FormatPeriodReport(PeriodReport report) + { + return FormatPeriodReportLine( + periodNumber: report.PeriodNumber.ToString(), + totalSlots: report.TotalNumSlots.ToString(), + totalRequired: report.TotalProofsRequired.ToString(), + totalMissed: report.MissedProofs.Length.ToString() + ); + } + + private string FormatPeriodReportLine(string periodNumber, string totalSlots, string totalRequired, string totalMissed) + { + return $"{periodNumber.PadLeft(10)} {totalSlots.PadLeft(10)} {totalRequired.PadLeft(10)} {totalMissed.PadLeft(10)}"; + } + private void AddRequestBlock(RequestEvent requestEvent, string eventName, params string[] content) { var blockNumber = $"[{requestEvent.Block.BlockNumber} {FormatDateTime(requestEvent.Block.Utc)}]"; diff --git a/Tools/TestNetRewarder/HistoricState.cs b/Tools/TestNetRewarder/HistoricState.cs deleted file mode 100644 index 2e744145..00000000 --- a/Tools/TestNetRewarder/HistoricState.cs +++ /dev/null @@ -1,97 +0,0 @@ -using CodexContractsPlugin; -using CodexContractsPlugin.Marketplace; -using Newtonsoft.Json; -using Utils; - -namespace TestNetRewarder -{ - public class HistoricState - { - private readonly List storageRequests = new List(); - - public StorageRequest[] StorageRequests { get { return storageRequests.ToArray(); } } - - public void ProcessNewRequests(Request[] requests) - { - storageRequests.AddRange(requests.Select(r => new StorageRequest(r))); - } - - public void UpdateStorageRequests(ICodexContracts contracts) - { - foreach (var r in storageRequests) r.Update(contracts); - } - - public void CleanUpOldRequests() - { - storageRequests.RemoveAll(r => - r.State == RequestState.Cancelled || - r.State == RequestState.Finished || - r.State == RequestState.Failed - ); - } - - public string EntireString() - { - return JsonConvert.SerializeObject(StorageRequests); - } - - public HistoricState() - { - } - - public HistoricState(StorageRequest[] requests) - { - storageRequests.AddRange(requests); - } - } - - public class StorageRequest - { - public StorageRequest(Request request) - { - Request = request; - Hosts = Array.Empty(); - } - - public Request Request { get; } - public EthAddress[] Hosts { get; private set; } - public RequestState State { get; private set; } - - [JsonIgnore] - public bool RecentlyStarted { get; private set; } - - [JsonIgnore] - public bool RecentlyFinished { get; private set; } - - public void Update(ICodexContracts contracts) - { - var newHosts = GetHosts(contracts); - - var newState = contracts.GetRequestState(Request); - - RecentlyStarted = - State == RequestState.New && - newState == RequestState.Started; - - RecentlyFinished = - State == RequestState.Started && - newState == RequestState.Finished; - - State = newState; - Hosts = newHosts; - } - - private EthAddress[] GetHosts(ICodexContracts contracts) - { - var result = new List(); - - for (decimal i = 0; i < Request.Ask.Slots; i++) - { - var host = contracts.GetSlotHost(Request, i); - if (host != null) result.Add(host); - } - - return result.ToArray(); - } - } -} diff --git a/Tools/TestNetRewarder/Processor.cs b/Tools/TestNetRewarder/Processor.cs index 08381284..3e9f6789 100644 --- a/Tools/TestNetRewarder/Processor.cs +++ b/Tools/TestNetRewarder/Processor.cs @@ -14,12 +14,14 @@ namespace TestNetRewarder private readonly Configuration config; private readonly BotClient client; private readonly ILog log; + private DateTime lastPeriodUpdateUtc; public Processor(Configuration config, BotClient client, ICodexContracts contracts, ILog log) { this.config = config; this.client = client; this.log = log; + lastPeriodUpdateUtc = DateTime.UtcNow; builder = new RequestBuilder(); rewardChecker = new RewardChecker(builder); @@ -68,6 +70,7 @@ namespace TestNetRewarder private async Task ProcessEvents(TimeRange timeRange) { var numberOfChainEvents = chainState.Update(timeRange.To); + ProcessPeriodUpdate(); var events = eventsFormatter.GetEvents(); var errors = eventsFormatter.GetErrors(); @@ -79,5 +82,13 @@ namespace TestNetRewarder } return numberOfChainEvents; } + + private void ProcessPeriodUpdate() + { + if (DateTime.UtcNow < (lastPeriodUpdateUtc + TimeSpan.FromHours(1.0))) return; + lastPeriodUpdateUtc = DateTime.UtcNow; + + eventsFormatter.ProcessPeriodReports(chainState.PeriodMonitor.GetAndClearReports()); + } } }