diff --git a/Framework/KubernetesWorkflow/Types/RunningContainer.cs b/Framework/KubernetesWorkflow/Types/RunningContainer.cs index 81faf154..fc7d64b2 100644 --- a/Framework/KubernetesWorkflow/Types/RunningContainer.cs +++ b/Framework/KubernetesWorkflow/Types/RunningContainer.cs @@ -27,7 +27,7 @@ namespace KubernetesWorkflow.Types public Address GetAddress(string portTag) { var addresses = Addresses.Where(a => a.PortTag == portTag).ToArray(); - if (!addresses.Any()) throw new Exception("No addresses found for portTag: " + portTag); + if (addresses.Length == 0) throw new Exception("No addresses found for portTag: " + portTag); var select = SelectAddress(addresses); return select.Address; diff --git a/ProjectPlugins/CodexClient/CodexNode.cs b/ProjectPlugins/CodexClient/CodexNode.cs index 4a444117..7bf5f4d2 100644 --- a/ProjectPlugins/CodexClient/CodexNode.cs +++ b/ProjectPlugins/CodexClient/CodexNode.cs @@ -299,7 +299,7 @@ namespace CodexClient private void InitializePeerNodeId() { - var debugInfo = Time.Retry(codexAccess.GetDebugInfo, "ensure online"); + var debugInfo = codexAccess.GetDebugInfo(); if (!debugInfo.Version.IsValid()) { throw new Exception($"Invalid version information received from Codex node {GetName()}: {debugInfo.Version}"); diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs index 1f260c7d..8e64302c 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs @@ -1,6 +1,7 @@ using BlockchainUtils; using CodexContractsPlugin.Marketplace; using Logging; +using Nethereum.Hex.HexConvertors.Extensions; using System.Numerics; using Utils; @@ -13,7 +14,7 @@ namespace CodexContractsPlugin.ChainMonitor void OnRequestFulfilled(RequestEvent requestEvent); void OnRequestCancelled(RequestEvent requestEvent); void OnRequestFailed(RequestEvent requestEvent); - void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex); + void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair); void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex); void OnSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex); void OnProofSubmitted(BlockTimeEntry block, string id); @@ -118,7 +119,17 @@ namespace CodexContractsPlugin.ChainMonitor private void ApplyEvent(Request request) { if (requests.Any(r => Equal(r.Request.RequestId, request.RequestId))) - throw new Exception("Received NewRequest event for id that already exists."); + { + var r = FindRequest(request); + if (r == null) throw new Exception("ChainState is inconsistent. Received already-known requestId that's not known."); + + if (request.Block.BlockNumber != r.Request.Block.BlockNumber) throw new Exception("Same request found in different blocks."); + if (request.Client != r.Request.Client) throw new Exception("Same request belongs to different clients."); + if (request.Content.Cid.ToHex() != r.Request.Content.Cid.ToHex()) throw new Exception("Same request has different CIDs."); + + log.Log("Received the same request-creation event multiple times."); + return; + } var newRequest = new ChainStateRequest(log, request, RequestState.New); requests.Add(newRequest); @@ -154,16 +165,18 @@ namespace CodexContractsPlugin.ChainMonitor { var r = FindRequest(@event); if (r == null) return; - r.Hosts.Add(@event.Host, (int)@event.SlotIndex); + var slotIndex = (int)@event.SlotIndex; + var isRepair = !r.Hosts.IsFilled(slotIndex) && r.Hosts.WasPreviouslyFilled(slotIndex); + r.Hosts.HostFillsSlot(@event.Host, slotIndex); r.Log($"[{@event.Block.BlockNumber}] SlotFilled (host:'{@event.Host}', slotIndex:{@event.SlotIndex})"); - handler.OnSlotFilled(new RequestEvent(@event.Block, r), @event.Host, @event.SlotIndex); + handler.OnSlotFilled(new RequestEvent(@event.Block, r), @event.Host, @event.SlotIndex, isRepair); } private void ApplyEvent(SlotFreedEventDTO @event) { var r = FindRequest(@event); if (r == null) return; - r.Hosts.RemoveHost((int)@event.SlotIndex); + r.Hosts.SlotFreed((int)@event.SlotIndex); r.Log($"[{@event.Block.BlockNumber}] SlotFreed (slotIndex:{@event.SlotIndex})"); handler.OnSlotFreed(new RequestEvent(@event.Block, r), @event.SlotIndex); } diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateChangeHandlerMux.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateChangeHandlerMux.cs index a9a46a25..b5b4ade4 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateChangeHandlerMux.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateChangeHandlerMux.cs @@ -38,9 +38,9 @@ namespace CodexContractsPlugin.ChainMonitor foreach (var handler in Handlers) handler.OnRequestFulfilled(requestEvent); } - public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { - foreach (var handler in Handlers) handler.OnSlotFilled(requestEvent, host, slotIndex); + foreach (var handler in Handlers) handler.OnSlotFilled(requestEvent, host, slotIndex, isRepair); } public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex) diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateRequest.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateRequest.cs index 408d2746..2fa50e78 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateRequest.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainStateRequest.cs @@ -55,13 +55,25 @@ namespace CodexContractsPlugin.ChainMonitor public class RequestHosts { private readonly Dictionary hosts = new Dictionary(); + private readonly List filled = new List(); - public void Add(EthAddress host, int index) + public void HostFillsSlot(EthAddress host, int index) { hosts.Add(index, host); + filled.Add(index); + } + + public bool IsFilled(int index) + { + return hosts.ContainsKey(index); + } + + public bool WasPreviouslyFilled(int index) + { + return filled.Contains(index); } - public void RemoveHost(int index) + public void SlotFreed(int index) { hosts.Remove(index); } diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/DoNothingChainEventHandler.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/DoNothingChainEventHandler.cs index 43407998..b7a7f7fa 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/DoNothingChainEventHandler.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/DoNothingChainEventHandler.cs @@ -26,7 +26,7 @@ namespace CodexContractsPlugin.ChainMonitor { } - public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { } diff --git a/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs b/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs index c7e900be..b9ee6389 100644 --- a/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs +++ b/ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs @@ -35,12 +35,15 @@ namespace CodexContractsPlugin var container = containers.Containers[0]; Log("Container started."); + var watcher = workflow.CreateCrashWatcher(container); + watcher.Start(); try { var result = DeployContract(container, workflow, gethNode); workflow.Stop(containers, waitTillStopped: false); + watcher.Stop(); Log("Container stopped."); return result; } diff --git a/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs b/ProjectPlugins/CodexContractsPlugin/Marketplace/Marketplace.cs index 2f2c8ede..a8549759 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 = "0x60c060405234801561001057600080fd5b50604051614faf380380614faf83398101604081905261002f9161053b565b602083015180516040850151516001805460ff191660ff90921691909117905582906001600160401b03811660000361007b5760405163015536c760e51b815260040160405180910390fd5b6001600160401b031660805261010043116100a9576040516338f5f66160e11b815260040160405180910390fd5b8151600280546020850151604086015160608701516001600160401b039586166001600160801b0319909416939093176801000000000000000095909216949094021761ffff60801b1916600160801b60ff9485160260ff60881b191617600160881b9390911692909202919091178155608083015183919060039061012f90826106d9565b5050600480546001600160a01b0319166001600160a01b0393841617905550831660a05250825151606460ff909116111561017d576040516302bd816360e41b815260040160405180910390fd5b606483600001516040015160ff1611156101aa576040516354e5e0ab60e11b815260040160405180910390fd5b825160408101516020909101516064916101c391610797565b60ff1611156101e5576040516317ff9d0f60e21b815260040160405180910390fd5b82518051600b805460208085015160408087015160609788015160ff90811663010000000263ff0000001992821662010000029290921663ffff0000199482166101000261ffff1990971698821698909817959095179290921695909517178355808801518051600c80549383015196830151978301518516600160881b0260ff60881b1998909516600160801b029790971661ffff60801b196001600160401b0397881668010000000000000000026001600160801b031990951697909216969096179290921791909116939093171783556080820151869391929190600d906102d090826106d9565b50505060408201515160038201805460ff191660ff909216919091179055606090910151600490910180546001600160401b0319166001600160401b03909216919091179055506107c8915050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156103575761035761031f565b60405290565b604051608081016001600160401b03811182821017156103575761035761031f565b604051601f8201601f191681016001600160401b03811182821017156103a7576103a761031f565b604052919050565b805160ff811681146103c057600080fd5b919050565b80516001600160401b03811681146103c057600080fd5b600060a082840312156103ee57600080fd5b6103f6610335565b9050610401826103c5565b815261040f602083016103c5565b6020820152610420604083016103af565b6040820152610431606083016103af565b606082015260808201516001600160401b0381111561044f57600080fd5b8201601f8101841361046057600080fd5b80516001600160401b038111156104795761047961031f565b61048c601f8201601f191660200161037f565b8181528560208385010111156104a157600080fd5b60005b828110156104c0576020818501810151838301820152016104a4565b5060006020838301015280608085015250505092915050565b6000602082840312156104eb57600080fd5b604051602081016001600160401b038111828210171561050d5761050d61031f565b60405290508061051c836103af565b905292915050565b80516001600160a01b03811681146103c057600080fd5b60008060006060848603121561055057600080fd5b83516001600160401b0381111561056657600080fd5b840180860360e081121561057957600080fd5b61058161035d565b608082121561058f57600080fd5b61059761035d565b91506105a2836103af565b82526105b0602084016103af565b60208301526105c1604084016103af565b60408301526105d2606084016103af565b60608301529081526080820151906001600160401b038211156105f457600080fd5b610600888385016103dc565b60208201526106128860a085016104d9565b604082015261062360c084016103c5565b6060820152945061063991505060208501610524565b915061064760408501610524565b90509250925092565b600181811c9082168061066457607f821691505b60208210810361068457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156106d457806000526020600020601f840160051c810160208510156106b15750805b601f840160051c820191505b818110156106d157600081556001016106bd565b50505b505050565b81516001600160401b038111156106f2576106f261031f565b610706816107008454610650565b8461068a565b6020601f82116001811461073a57600083156107225750848201515b600019600385901b1c1916600184901b1784556106d1565b600084815260208120601f198516915b8281101561076a578785015182556020948501946001909201910161074a565b50848210156107885786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60ff81811683821602908116908181146107c157634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a05161478a610825600039600081816104dd01528181610f76015281816120390152818161266801528181612718015281816128a7015281816129570152612d790152600081816135b801526138bd015261478a6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80636e2b54ee11610104578063c0cc4add116100a2578063e8aa0a0711610071578063e8aa0a071461047f578063f752196b14610492578063fb1e61ca146104bb578063fc0c546a146104db57600080fd5b8063c0cc4add14610433578063c5d4335114610446578063d02bbe3314610459578063d1bb36b61461046c57600080fd5b8063a29c29a4116100de578063a29c29a4146103bd578063a3a0807e146103d0578063b396dc79146103f3578063be5cdc481461041357600080fd5b80636e2b54ee1461038f5780639777b72c146103a257806399b6da0c146103aa57600080fd5b8063329b5a0b1161017157806351a766421161014b57806351a766421461030e5780635da73835146103215780636b00c8cf146103365780636c70bee91461037a57600080fd5b8063329b5a0b146102a3578063458d2bf1146102d65780634641dce6146102e957600080fd5b806312827602116101ad57806312827602146102395780631d873c1b1461024c578063237d84821461025f57806326d6f8341461027257600080fd5b806302fa8e65146101d457806305b90773146102045780630aefaabe14610224575b600080fd5b6101e76101e2366004613958565b610501565b6040516001600160401b0390911681526020015b60405180910390f35b610217610212366004613958565b6105df565b6040516101fb9190613987565b6102376102323660046139b6565b610702565b005b610237610247366004613a1d565b610895565b61023761025a366004613a60565b610966565b61023761026d366004613a1d565b610e18565b610295610280366004613958565b60009081526012602052604090206003015490565b6040519081526020016101fb565b6101e76102b1366004613958565b600090815260116020526040902060020154600160c01b90046001600160401b031690565b6102956102e4366004613958565b611066565b6102fc6102f7366004613958565b61107f565b60405160ff90911681526020016101fb565b61029561031c366004613958565b611092565b6103296110f1565b6040516101fb9190613aa0565b610362610344366004613958565b6000908152601260205260409020600401546001600160a01b031690565b6040516001600160a01b0390911681526020016101fb565b610382611118565b6040516101fb9190613b7e565b61023761039d366004613958565b61128f565b61032961129c565b6102376103b8366004613c06565b6112bb565b6102376103cb366004613958565b611801565b6103e36103de366004613958565b611853565b60405190151581526020016101fb565b610406610401366004613958565b61188f565b6040516101fb9190613d35565b610426610421366004613958565b611b71565b6040516101fb9190613d70565b6103e3610441366004613958565b611c3f565b610237610454366004613d84565b611c52565b6103e3610467366004613a1d565b6120d3565b61023761047a366004613a1d565b612175565b61023761048d366004613da9565b6121ba565b6101e76104a0366004613958565b6000908152600660205260409020546001600160401b031690565b6104ce6104c9366004613958565b612333565b6040516101fb9190613dd7565b7f0000000000000000000000000000000000000000000000000000000000000000610362565b60008061050d836105df565b9050600081600481111561052357610523613971565b14806105405750600181600481111561053e5761053e613971565b145b1561056c575050600090815260116020526040902060020154600160801b90046001600160401b031690565b600281600481111561058057610580613971565b036105ac575050600090815260116020526040902060020154600160c01b90046001600160401b031690565b6000838152601160205260409020600201546105d890600160801b90046001600160401b031642612549565b9392505050565b60008181526010602052604081205482906001600160a01b031661061657604051635eeb253d60e11b815260040160405180910390fd5b600083815260116020526040812090815460ff16600481111561063b5761063b613971565b14801561067a5750600084815260116020526040902060020154600160c01b90046001600160401b03166001600160401b0316426001600160401b0316115b156106895760029250506106fc565b6001815460ff1660048111156106a1576106a1613971565b14806106c257506000815460ff1660048111156106c0576106c0613971565b145b80156106e6575060028101546001600160401b03600160801b909104811642909116115b156106f55760039250506106fc565b5460ff1691505b50919050565b826000808281526012602052604090205460ff16600681111561072757610727613971565b0361074557604051638b41ec7f60e01b815260040160405180910390fd5b600084815260126020526040902060048101546001600160a01b03163314610799576040517f57a6f4e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107a486611b71565b905060048160068111156107ba576107ba613971565b036107f1576040517fc2cbf77700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600281600681111561080557610805613971565b0361081f5761081a8260010154878787612559565b61088d565b600581600681111561083357610833613971565b036108485761081a82600101548787876127a2565b600381600681111561085c5761085c613971565b0361086b5761081a33876129eb565b600181600681111561087f5761087f613971565b0361088d5761088d86612a0d565b505050505050565b61089f82826120d3565b6108d5576040517f424a04ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108e18383612c5d565b60008181526020819052604090209091506108fc9033612ca2565b50600154600082815260208190526040902060ff9091169061091d90612cb7565b03610961576040516001600160401b038316815283907fc8e6c955744189a19222ec226b72ac1435d88d5745252dac56e6f679f64c037a9060200160405180910390a25b505050565b60008381526010602052604090205483906001600160a01b031661099d57604051635eeb253d60e11b815260040160405180910390fd5b600084815260106020526040902060048101546001600160401b03908116908516106109f5576040517f3b920b8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a018686612c5d565b6000818152602081905260409020909150610a1c9033612cc1565b610a52576040517fd651ce1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152601260209081526040808320600181018a90556002810180546fffffffffffffffff00000000000000001916600160401b6001600160401b038c1602179055898452601190925282209091610aab84611b71565b6006811115610abc57610abc613971565b14158015610ae457506006610ad084611b71565b6006811115610ae157610ae1613971565b14155b15610b1b576040517fff556acf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048201805473ffffffffffffffffffffffffffffffffffffffff1916331790556002820180546001600160401b03421667ffffffffffffffff19909116179055610b8c83600090815260056020526040902080546001600160401b03421667ffffffffffffffff19909116179055565b610b9683876121ba565b60028101805460019190600090610bb79084906001600160401b0316613e00565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610bfc888360020160009054906101000a90046001600160401b0316612ce3565b816001016000828254610c0f9190613e1f565b90915550506040805160e081018252600186015481526002860154602082015260038601549181019190915260048501546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c08201526000908190610c8890612d12565b90506006610c9586611b71565b6006811115610ca657610ca6613971565b03610cd957600b54606490610cbe9060ff1683613e32565b610cc89190613e5f565b610cd29082613e1f565b9150610cdd565b8091505b610ce73383612d31565b8160136000016000828254610cfc9190613e73565b9091555050600384018190556004840154610d20906001600160a01b031686612e05565b835460ff191660011784556040516001600160401b038a1681528a907f8f301470a994578b52323d625dfbf827ca5208c81747d3459be7b8867baec3ec9060200160405180910390a2600486015460028401546001600160401b039081169116148015610da257506000835460ff166004811115610da057610da0613971565b145b15610e0c57825460ff191660011783556002830180546001600160401b034216600160401b026fffffffffffffffff0000000000000000199091161790556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b816001610e2482611b71565b6006811115610e3557610e35613971565b14610e535760405163ae9dcffd60e01b815260040160405180910390fd5b610e5d8383612e27565b6000838152601260209081526040808320600180820154855260108452828520600b54845160e08101865292820154835260028201549583019590955260038101549382019390935260048301546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0820152909391926064916201000090910460ff1690610f0090612d12565b610f0a9190613e32565b610f149190613e5f565b600b54909150600090606490610f34906301000000900460ff1684613e32565b610f3e9190613e5f565b90508060136001016000828254610f559190613e73565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610feb9190613e86565b61100857604051637c2ccffd60e11b815260040160405180910390fd5b8184600301600082825461101c9190613e1f565b9091555050600b5460008881526006602052604090205461010090910460ff16906001600160401b03166001600160401b03161061105d5761105d87612a0d565b50505050505050565b600061107982611074612eaa565b612eb5565b92915050565b60006110798261108d612eaa565b612ec9565b60008181526012602090815260408083206001810154845260109092528220600c54610100906110cc90600160801b900460ff1682613ea8565b60018301546110df9161ffff1690613e32565b6110e99190613e5f565b949350505050565b336000908152600a602052604090206060906111139061111090612f5b565b90565b905090565b6111206138e2565b604080516101008082018352600b805460ff8082166080808701918252948304821660a080880191909152620100008404831660c08801526301000000909304821660e0870152855285519182018652600c80546001600160401b038082168552600160401b820416602085810191909152600160801b82048416988501989098527101000000000000000000000000000000000090049091166060830152600d80549596939593870194929391928401916111db90613ec2565b80601f016020809104026020016040519081016040528092919081815260200182805461120790613ec2565b80156112545780601f1061122957610100808354040283529160200191611254565b820191906000526020600020905b81548152906001019060200180831161123757829003601f168201915b5050509190925250505081526040805160208181018352600385015460ff1682528301526004909201546001600160401b0316910152919050565b6112998133611c52565b50565b3360009081526009602052604090206060906111139061111090612f5b565b60006112ce6112c983614053565b612f68565b9050336112de602084018461415c565b6001600160a01b031614611305576040516334c69e3160e11b815260040160405180910390fd5b6000818152601060205260409020546001600160a01b031615611354576040517ffc7d069000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61136661014083016101208401614179565b6001600160401b031615806113ad575061138660e0830160c08401614179565b6001600160401b03166113a161014084016101208501614179565b6001600160401b031610155b156113e4576040517fdf63f61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113f460a0830160808401614179565b6001600160401b0316600003611436576040517f535ed2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144660a0830160808401614179565b6001600160401b0316611460610100840160e08501614179565b6001600160401b031611156114a1576040517fb9551ab100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114b160e0830160c08401614179565b6001600160401b03166000036114f3576040517f090a5ecd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020820135600003611531576040517f6aba7aae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606082013560000361156f576040517ffb7df0c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201356000036115ad576040517f47ba51c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115bb610100830183614196565b6115c590806141b6565b9050600003611600576040517f86f8cf9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f546001600160401b031661161c60e0840160c08501614179565b6001600160401b0316111561165d576040517f1267b3f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260106020526040902082906116778282614356565b5061168a905060e0830160c08401614179565b6116949042613e00565b600082815260116020526040902060020180546001600160401b0392909216600160801b0267ffffffffffffffff60801b199092169190911790556116e161014083016101208401614179565b6116eb9042613e00565b600082815260116020908152604090912060020180546001600160401b0393909316600160c01b0277ffffffffffffffffffffffffffffffffffffffffffffffff9093169290921790915561174c906117469084018461415c565b82612f98565b600061175f61175a84614053565b612fba565b600083815260116020526040812060010182905560138054929350839290919061178a908490613e73565b9091555061179a90503382612d31565b6000828152601160209081526040918290206002015491517f1bf9c457accf8703dbf7cdf1b58c2f74ddf2e525f98155c70b3d318d74609bd8926117f492869290880191600160c01b90046001600160401b03169061450a565b60405180910390a1505050565b806000808281526012602052604090205460ff16600681111561182657611826613971565b0361184457604051638b41ec7f60e01b815260040160405180910390fd5b61184f823333610702565b5050565b600080600061186984611864612eaa565b612ff6565b90925090508180156110e95750600254600160801b900460ff9081169116109392505050565b611912604051806040016040528061394b6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b816000808281526012602052604090205460ff16600681111561193757611937613971565b0361195557604051638b41ec7f60e01b815260040160405180910390fd5b60008381526012602052604090206119e6604051806040016040528061394b6040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b600180830154600090815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e08101865295830154865260028301548685015260038301548686015260048301546001600160401b038082166060890152600160401b820481166080890152600160801b8204811692880192909252600160c01b90041660c0860152918201939093528151808301835260058401805492949385019282908290611a9b90613ec2565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac790613ec2565b8015611b145780601f10611ae957610100808354040283529160200191611b14565b820191906000526020600020905b815481529060010190602001808311611af757829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0390811683830152600890930154604090920191909152918352600290930154600160401b900490921691810191909152915050919050565b600081815260126020526040812060018101548203611b935750600092915050565b6000611ba282600101546105df565b90506004825460ff166006811115611bbc57611bbc613971565b03611bcb575060049392505050565b6002816004811115611bdf57611bdf613971565b03611bee575060059392505050565b6003816004811115611c0257611c02613971565b03611c11575060029392505050565b6004816004811115611c2557611c25613971565b03611c34575060039392505050565b505460ff1692915050565b600061107982611c4d612eaa565b6130ae565b60008281526010602052604090205482906001600160a01b0316611c8957604051635eeb253d60e11b815260040160405180910390fd5b6000838152601060209081526040808320601190925290912081546001600160a01b03163314611ccc576040516334c69e3160e11b815260040160405180910390fd5b6000611cd7866105df565b90506002816004811115611ced57611ced613971565b14158015611d0d57506004816004811115611d0a57611d0a613971565b14155b8015611d2b57506003816004811115611d2857611d28613971565b14155b15611d62576040517fc00b5b5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003611da0576040517fbd8bdd9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002816004811115611db457611db4613971565b03611e5257815460ff1916600217825560405186907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a2600086815260116020526040902060020154611e1c908790600160c01b90046001600160401b0316612ce3565b6002830154611e3491906001600160401b0316613e32565b826001016000828254611e479190613e73565b90915550611fdf9050565b6004816004811115611e6657611e66613971565b03611fd3576040805160a0808201835285546001600160a01b03168252825160e08101845260018701548152600287015460208281019190915260038801548286015260048801546001600160401b038082166060850152600160401b820481166080850152600160801b8204811694840194909452600160c01b900490921660c08201529082015281518083018352600586018054611fc994889390850192909182908290611f1590613ec2565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4190613ec2565b8015611f8e5780601f10611f6357610100808354040283529160200191611f8e565b820191906000526020600020905b815481529060010190602001808311611f7157829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b031690820152600890910154604090910152612fba565b6001830155611fdf565b815460ff191660031782555b8254611ff4906001600160a01b0316876130e8565b60018201546014805482919060009061200e908490613e73565b909155505060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a69190613e86565b6120c357604051637c2ccffd60e11b815260040160405180910390fd5b5050600060019091015550505050565b600033816120e18585612c5d565b905060006120ee82611b71565b9050600081600681111561210457612104613971565b14806121215750600681600681111561211f5761211f613971565b145b801561214a5750600154600083815260208190526040902060ff9091169061214890612cb7565b105b801561216b575060008281526020819052604090206121699084612cc1565b155b9695505050505050565b81600161218182611b71565b600681111561219257612192613971565b146121b05760405163ae9dcffd60e01b815260040160405180910390fd5b610961838361310a565b6000828152601260209081526040808320600101548084526010909252909120546001600160a01b031661220157604051635eeb253d60e11b815260040160405180910390fd5b600083815260126020526040902060048101546001600160a01b03163314612255576040517fce351b9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001810154600090815260106020526040808220815160038082526080820190935290929181602001602082028036833701905050905061229d61229887611066565b6132a7565b816000815181106122b0576122b06145b7565b602090810291909101015260068201546122c9906132b8565b816001815181106122dc576122dc6145b7565b6020026020010181815250508260020160089054906101000a90046001600160401b03166001600160401b03168160028151811061231c5761231c6145b7565b60200260200101818152505061088d8686836132c4565b6123a86040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b60008281526010602052604090205482906001600160a01b03166123df57604051635eeb253d60e11b815260040160405180910390fd5b600083815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186526001840154815260028401548186015260038401548187015260048401546001600160401b038082166060840152600160401b820481166080840152600160801b8204811693830193909352600160c01b900490911660c0820152928101929092528251808401845260058201805493949293928501928290829061249390613ec2565b80601f01602080910402602001604051908101604052809291908181526020018280546124bf90613ec2565b801561250c5780601f106124e15761010080835404028352916020019161250c565b820191906000526020600020905b8154815290600101906020018083116124ef57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0316908201526008909101546040909101529392505050565b60008282188284100282186105d8565b60008481526010602052604090205484906001600160a01b031661259057604051635eeb253d60e11b815260040160405180910390fd5b600085815260116020908152604080832060108352818420815460ff191660031782558885526012909352922081546125d2906001600160a01b0316896130e8565b60048101546125ea906001600160a01b0316886129eb565b6002810154600090612606908a906001600160401b0316612ce3565b60038301549091506126188183613e73565b6014805460009061262a908490613e73565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156126b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d59190613e86565b6126f257604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038881166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015612761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127859190613e86565b610e0c57604051637c2ccffd60e11b815260040160405180910390fd5b60008481526010602052604090205484906001600160a01b03166127d957604051635eeb253d60e11b815260040160405180910390fd5b600084815260126020526040902060048101546127ff906001600160a01b0316866129eb565b60028101546000906128459088906001600160401b0316612840826000908152601160205260409020600201546001600160401b03600160c01b9091041690565b613462565b60038301549091506128578183613e73565b60148054600090612869908490613e73565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129149190613e86565b61293157604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156129a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c49190613e86565b6129e157604051637c2ccffd60e11b815260040160405180910390fd5b5050505050505050565b6001600160a01b0382166000908152600a602052604090206109619082613541565b60008181526012602090815260408083206001810154808552601190935292206002830154612a469083906001600160401b0316612ce3565b816001016000828254612a599190613e73565b90915550506004830154612a76906001600160a01b0316856129eb565b6000848152602081905260409020612a8d9061354d565b825460ff191660061783556002808401805467ffffffffffffffff1916905560006003850181905560048501805473ffffffffffffffffffffffffffffffffffffffff19169055908201805460019290612af19084906001600160401b03166145cd565b82546101009290920a6001600160401b038181021990931691831602179091556002850154604051600160401b90910490911681528391507f33ba8f7627565d89f7ada2a6b81ea532b7aa9b11e91a78312d6e1fca0bfcd1dc9060200160405180910390a26000848152600660205260409020805467ffffffffffffffff19169055600082815260106020526040812060028301546004820154919291612ba4916001600160401b0390811691166145cd565b60048301546001600160401b039182169250600160c01b90041681118015612be157506001835460ff166004811115612bdf57612bdf613971565b145b1561088d57825460ff19166004178355612bfc6001426145cd565b6002840180546001600160401b0392909216600160801b0267ffffffffffffffff60801b1990921691909117905560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a2505050505050565b60008282604051602001612c849291909182526001600160401b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b60006105d8836001600160a01b038416613556565b6000611079825490565b6001600160a01b038116600090815260018301602052604081205415156105d8565b6000828152601160205260408120600201546105d89084908490600160801b90046001600160401b0316613462565b600081608001516001600160401b031682604001516110799190613e32565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd906064016020604051808303816000875af1158015612dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de89190613e86565b61096157604051637c2ccffd60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a6020526040902061096190826135a5565b612e31828261310a565b60008281526008602090815260408083206001600160401b038086168552908352818420805460ff1916600190811790915586855260069093529083208054929390929091612e8291859116613e00565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505050565b6000611113426135b1565b60006105d8612ec48484612ec9565b6135dd565b600080612ed8610100436145ec565b60025490915060009061010090612f079071010000000000000000000000000000000000900460ff1686614600565b612f119190614622565b6001600160401b031690506000612f2a610100876145ec565b9050600061010082612f3c8587613e73565b612f469190613e73565b612f5091906145ec565b979650505050505050565b606060006105d883613637565b600081604051602001612f7b9190613dd7565b604051602081830303815290604052805190602001209050919050565b6001600160a01b038216600090815260096020526040902061096190826135a5565b6000612fc98260200151613693565b602083015160a0810151606090910151612fe39190614600565b6001600160401b03166110799190613e32565b600080600061300485611b71565b60008681526005602052604081205491925090613029906001600160401b03166135b1565b9050600182600681111561303f5761303f613971565b141580613053575061305185826136b2565b155b15613066576000809350935050506130a7565b6130708686612ec9565b9250600061307d846135dd565b9050600061308a88611092565b90508015806130a0575061309e81836145ec565b155b9550505050505b9250929050565b60008060006130bd8585612ff6565b90925090508180156130df575060025460ff600160801b909104811690821610155b95945050505050565b6001600160a01b03821660009081526009602052604090206109619082613541565b6000613115826136c8565b6001600160401b03169050428110613159576040517f6b4b1a4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025461317690600160401b90046001600160401b031682613e73565b42106131ae576040517fde55698e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602090815260408083206001600160401b038616845290915290205460ff161561320a576040517efab7d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61321483836130ae565b61324a576040517fd3ffa66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038616845290915290205460ff1615610961576040517f98e7e55100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060ff198216816110e9826136db565b6000806105d8836136db565b6000838152600760205260408120906132db612eaa565b6001600160401b0316815260208101919091526040016000205460ff161561332f576040517f3edef7db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546040517f94c8919d0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116916394c8919d91613379918691869101614650565b602060405180830381865afa158015613396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ba9190613e86565b6133f0576040517ffcd03a4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260408120600191613409612eaa565b6001600160401b031681526020808201929092526040908101600020805460ff19169315159390931790925590518481527f3b989d183b84b02259d7c14b34a9c9eb0fccb4c355a920d25e581e25aef4993d91016117f4565b60008381526010602052604081206001600160401b03808416908516106134b5576040517f56607cb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600183015481526002830154602082015260038301549181019190915260048201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c082015261352490613693565b61352e85856145cd565b6001600160401b03166130df9190613e32565b60006105d8838361374d565b61129981613847565b600081815260018301602052604081205461359d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611079565b506000611079565b60006105d88383613556565b60006110797f0000000000000000000000000000000000000000000000000000000000000000836146fa565b60008060ff83166135ef600143613e1f565b6135f99190613e1f565b409050600081900361360d5761360d614728565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561368757602002820191906000526020600020905b815481526020019060010190808311613673575b50505050509050919050565b600081608001516001600160401b031682602001516110799190613e32565b60006001600160401b03808416908316106105d8565b60006110796136d6836138a9565b6138b6565b7fff00000000000000000000000000000000000000000000000000000000000000811660015b60208110156106fc57600891821c9161371b908290613e32565b83901b7fff00000000000000000000000000000000000000000000000000000000000000169190911790600101613701565b60008181526001830160205260408120548015613836576000613771600183613e1f565b855490915060009061378590600190613e1f565b90508082146137ea5760008660000182815481106137a5576137a56145b7565b90600052602060002001549050808760000184815481106137c8576137c86145b7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806137fb576137fb61473e565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611079565b6000915050611079565b5092915050565b6000613851825490565b905060005b818110156138a157826001016000846000018381548110613879576138796145b7565b9060005260206000200154815260200190815260200160002060009055806001019050613856565b505060009055565b6000611079826001613e00565b60006110797f000000000000000000000000000000000000000000000000000000000000000083614600565b60408051610100810182526000608080830182815260a080850184905260c0850184905260e08501849052908452845190810185528281526020808201849052818601849052606080830185905292820192909252818401528351908101845290815290918201905b8152600060209091015290565b60006020828403121561396a57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b602081016005831061399b5761399b613971565b91905290565b6001600160a01b038116811461129957600080fd5b6000806000606084860312156139cb57600080fd5b8335925060208401356139dd816139a1565b915060408401356139ed816139a1565b809150509250925092565b6001600160401b038116811461129957600080fd5b8035613a18816139f8565b919050565b60008060408385031215613a3057600080fd5b823591506020830135613a42816139f8565b809150509250929050565b600061010082840312156106fc57600080fd5b60008060006101408486031215613a7657600080fd5b833592506020840135613a88816139f8565b9150613a978560408601613a4d565b90509250925092565b602080825282518282018190526000918401906040840190835b81811015613ad8578351835260209384019390920191600101613aba565b509095945050505050565b6000815180845260005b81811015613b0957602081850181015186830182015201613aed565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160401b0381511682526001600160401b03602082015116602083015260ff604082015116604083015260ff60608201511660608301526000608082015160a060808501526110e960a0850182613ae3565b602081526000825160ff815116602084015260ff602082015116604084015260ff604082015116606084015260ff606082015116608084015250602083015160e060a0840152613bd2610100840182613b29565b90506040840151613be960c08501825160ff169052565b5060608401516001600160401b03811660e0850152509392505050565b600060208284031215613c1857600080fd5b81356001600160401b03811115613c2e57600080fd5b820161016081850312156105d857600080fd5b6000815160408452613c566040850182613ae3565b602093840151949093019390935250919050565b6001600160a01b038151168252600060208201518051602085015260208101516040850152604081015160608501526001600160401b0360608201511660808501526001600160401b0360808201511660a08501526001600160401b0360a08201511660c08501526001600160401b0360c08201511660e0850152506040820151610160610100850152613d02610160850182613c41565b90506060830151613d1f6101208601826001600160401b03169052565b5060808301516101408501528091505092915050565b602081526000825160406020840152613d516060840182613c6a565b90506001600160401b0360208501511660408401528091505092915050565b602081016007831061399b5761399b613971565b60008060408385031215613d9757600080fd5b823591506020830135613a42816139a1565b6000806101208385031215613dbd57600080fd5b82359150613dce8460208501613a4d565b90509250929050565b6020815260006105d86020830184613c6a565b634e487b7160e01b600052601160045260246000fd5b6001600160401b03818116838216019081111561107957611079613dea565b8181038181111561107957611079613dea565b808202811582820484141761107957611079613dea565b634e487b7160e01b600052601260045260246000fd5b600082613e6e57613e6e613e49565b500490565b8082018082111561107957611079613dea565b600060208284031215613e9857600080fd5b815180151581146105d857600080fd5b61ffff828116828216039081111561107957611079613dea565b600181811c90821680613ed657607f821691505b6020821081036106fc57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613f2e57613f2e613ef6565b60405290565b60405160a081016001600160401b0381118282101715613f2e57613f2e613ef6565b60405160e081016001600160401b0381118282101715613f2e57613f2e613ef6565b604051601f8201601f191681016001600160401b0381118282101715613fa057613fa0613ef6565b604052919050565b600060408284031215613fba57600080fd5b613fc2613f0c565b905081356001600160401b03811115613fda57600080fd5b8201601f81018413613feb57600080fd5b80356001600160401b0381111561400457614004613ef6565b614017601f8201601f1916602001613f78565b81815285602083850101111561402c57600080fd5b81602084016020830137600060209282018301528352928301359282019290925292915050565b600081360361016081121561406757600080fd5b61406f613f34565b833561407a816139a1565b815260e0601f198301121561408e57600080fd5b614096613f56565b602085810135825260408087013591830191909152606086013590820152915060808401356140c4816139f8565b606083015260a08401356140d7816139f8565b608083015260c08401356140ea816139f8565b60a083015260e08401356140fd816139f8565b60c08301526020810191909152610100830135906001600160401b0382111561412557600080fd5b61413136838601613fa8565b60408201526141436101208501613a0d565b6060820152610140939093013560808401525090919050565b60006020828403121561416e57600080fd5b81356105d8816139a1565b60006020828403121561418b57600080fd5b81356105d8816139f8565b60008235603e198336030181126141ac57600080fd5b9190910192915050565b6000808335601e198436030181126141cd57600080fd5b8301803591506001600160401b038211156141e757600080fd5b6020019150368190038213156130a757600080fd5b60008135611079816139f8565b601f82111561096157806000526020600020601f840160051c810160208510156142305750805b601f840160051c820191505b81811015614250576000815560010161423c565b5050505050565b8135601e1983360301811261426b57600080fd5b820180356001600160401b038111801561428457600080fd5b81360360208401131561429657600080fd5b600090506142ae826142a88654613ec2565b86614209565b80601f8311600181146142e3578284156142cb5750848201602001355b600019600386901b1c1916600185901b178655614342565b600086815260209020601f19851690845b82811015614316576020858901810135835594850194600190920191016142f4565b50858210156143365760001960f88760031b161c19602085890101351681555b505060018460011b0186555b505050505060209190910135600190910155565b8135614361816139a1565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03919091161781556020820135600182015560408201356002820155606082013560038201556004810160808301356143b9816139f8565b815467ffffffffffffffff19166001600160401b0382161782555060a08301356143e2816139f8565b81546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff00000000000000001617815561445661442160c085016141fc565b825467ffffffffffffffff60801b191660809190911b77ffffffffffffffff0000000000000000000000000000000016178255565b6144ae61446560e085016141fc565b825477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff00000000000000000000000000000000000000000000000016178255565b506144c96144c0610100840184614196565b60058301614257565b6144fa6144d961012084016141fc565b600783016001600160401b0382166001600160401b03198254161781555050565b6101409190910135600890910155565b8381528235602080830191909152830135604080830191909152830135606080830191909152610120820190840135614542816139f8565b6001600160401b0381166080840152506080840135614560816139f8565b6001600160401b03811660a08401525060a084013561457e816139f8565b6001600160401b03811660c08401525061459a60c08501613a0d565b6001600160401b0390811660e084015283166101008301526110e9565b634e487b7160e01b600052603260045260246000fd5b6001600160401b03828116828216039081111561107957611079613dea565b6000826145fb576145fb613e49565b500690565b6001600160401b03818116838216029081169081811461384057613840613dea565b60006001600160401b0383168061463b5761463b613e49565b806001600160401b0384160691505092915050565b82358152602080840135908201526000610120820161467f604084016040870180358252602090810135910152565b614699608084016080870180358252602090810135910152565b6146b360c0840160c0870180358252602090810135910152565b610120610100840152835190819052602084019061014084019060005b818110156146ee5783518352602093840193909201916001016146d0565b50909695505050505050565b60006001600160401b0383168061471357614713613e49565b806001600160401b0384160491505092915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212208753932439ab3be782432684ba36d249b5e5029b7c1b55364b935c22d15237d664736f6c634300081c0033"; + public static string BYTECODE = "0x60c060405234801561001057600080fd5b50604051614fab380380614fab83398101604081905261002f9161053b565b602083015180516040850151516001805460ff191660ff90921691909117905582906001600160401b03811660000361007b5760405163015536c760e51b815260040160405180910390fd5b6001600160401b031660805261010043116100a9576040516338f5f66160e11b815260040160405180910390fd5b8151600280546020850151604086015160608701516001600160401b039586166001600160801b0319909416939093176801000000000000000095909216949094021761ffff60801b1916600160801b60ff9485160260ff60881b191617600160881b9390911692909202919091178155608083015183919060039061012f90826106d9565b5050600480546001600160a01b0319166001600160a01b0393841617905550831660a05250825151606460ff909116111561017d576040516302bd816360e41b815260040160405180910390fd5b606483600001516040015160ff1611156101aa576040516354e5e0ab60e11b815260040160405180910390fd5b825160408101516020909101516064916101c391610797565b60ff1611156101e5576040516317ff9d0f60e21b815260040160405180910390fd5b82518051600b805460208085015160408087015160609788015160ff90811663010000000263ff0000001992821662010000029290921663ffff0000199482166101000261ffff1990971698821698909817959095179290921695909517178355808801518051600c80549383015196830151978301518516600160881b0260ff60881b1998909516600160801b029790971661ffff60801b196001600160401b0397881668010000000000000000026001600160801b031990951697909216969096179290921791909116939093171783556080820151869391929190600d906102d090826106d9565b50505060408201515160038201805460ff191660ff909216919091179055606090910151600490910180546001600160401b0319166001600160401b03909216919091179055506107c8915050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156103575761035761031f565b60405290565b604051608081016001600160401b03811182821017156103575761035761031f565b604051601f8201601f191681016001600160401b03811182821017156103a7576103a761031f565b604052919050565b805160ff811681146103c057600080fd5b919050565b80516001600160401b03811681146103c057600080fd5b600060a082840312156103ee57600080fd5b6103f6610335565b9050610401826103c5565b815261040f602083016103c5565b6020820152610420604083016103af565b6040820152610431606083016103af565b606082015260808201516001600160401b0381111561044f57600080fd5b8201601f8101841361046057600080fd5b80516001600160401b038111156104795761047961031f565b61048c601f8201601f191660200161037f565b8181528560208385010111156104a157600080fd5b60005b828110156104c0576020818501810151838301820152016104a4565b5060006020838301015280608085015250505092915050565b6000602082840312156104eb57600080fd5b604051602081016001600160401b038111828210171561050d5761050d61031f565b60405290508061051c836103af565b905292915050565b80516001600160a01b03811681146103c057600080fd5b60008060006060848603121561055057600080fd5b83516001600160401b0381111561056657600080fd5b840180860360e081121561057957600080fd5b61058161035d565b608082121561058f57600080fd5b61059761035d565b91506105a2836103af565b82526105b0602084016103af565b60208301526105c1604084016103af565b60408301526105d2606084016103af565b60608301529081526080820151906001600160401b038211156105f457600080fd5b610600888385016103dc565b60208201526106128860a085016104d9565b604082015261062360c084016103c5565b6060820152945061063991505060208501610524565b915061064760408501610524565b90509250925092565b600181811c9082168061066457607f821691505b60208210810361068457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156106d457806000526020600020601f840160051c810160208510156106b15750805b601f840160051c820191505b818110156106d157600081556001016106bd565b50505b505050565b81516001600160401b038111156106f2576106f261031f565b610706816107008454610650565b8461068a565b6020601f82116001811461073a57600083156107225750848201515b600019600385901b1c1916600184901b1784556106d1565b600084815260208120601f198516915b8281101561076a578785015182556020948501946001909201910161074a565b50848210156107885786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60ff81811683821602908116908181146107c157634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a051614786610825600039600081816104dd01528181610f76015281816120350152818161266401528181612714015281816128a3015281816129530152612d750152600081816135b401526138b901526147866000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80636e2b54ee11610104578063c0cc4add116100a2578063e8aa0a0711610071578063e8aa0a071461047f578063f752196b14610492578063fb1e61ca146104bb578063fc0c546a146104db57600080fd5b8063c0cc4add14610433578063c5d4335114610446578063d02bbe3314610459578063d1bb36b61461046c57600080fd5b8063a29c29a4116100de578063a29c29a4146103bd578063a3a0807e146103d0578063b396dc79146103f3578063be5cdc481461041357600080fd5b80636e2b54ee1461038f5780639777b72c146103a257806399b6da0c146103aa57600080fd5b8063329b5a0b1161017157806351a766421161014b57806351a766421461030e5780635da73835146103215780636b00c8cf146103365780636c70bee91461037a57600080fd5b8063329b5a0b146102a3578063458d2bf1146102d65780634641dce6146102e957600080fd5b806312827602116101ad57806312827602146102395780631d873c1b1461024c578063237d84821461025f57806326d6f8341461027257600080fd5b806302fa8e65146101d457806305b90773146102045780630aefaabe14610224575b600080fd5b6101e76101e2366004613954565b610501565b6040516001600160401b0390911681526020015b60405180910390f35b610217610212366004613954565b6105df565b6040516101fb9190613983565b6102376102323660046139b2565b610702565b005b610237610247366004613a19565b610895565b61023761025a366004613a5c565b610966565b61023761026d366004613a19565b610e18565b610295610280366004613954565b60009081526012602052604090206003015490565b6040519081526020016101fb565b6101e76102b1366004613954565b600090815260116020526040902060020154600160c01b90046001600160401b031690565b6102956102e4366004613954565b611066565b6102fc6102f7366004613954565b61107f565b60405160ff90911681526020016101fb565b61029561031c366004613954565b611092565b6103296110f1565b6040516101fb9190613a9c565b610362610344366004613954565b6000908152601260205260409020600401546001600160a01b031690565b6040516001600160a01b0390911681526020016101fb565b610382611118565b6040516101fb9190613b7a565b61023761039d366004613954565b61128f565b61032961129c565b6102376103b8366004613c02565b6112bb565b6102376103cb366004613954565b611801565b6103e36103de366004613954565b611853565b60405190151581526020016101fb565b610406610401366004613954565b61188f565b6040516101fb9190613d31565b610426610421366004613954565b611b6d565b6040516101fb9190613d6c565b6103e3610441366004613954565b611c3b565b610237610454366004613d80565b611c4e565b6103e3610467366004613a19565b6120cf565b61023761047a366004613a19565b612171565b61023761048d366004613da5565b6121b6565b6101e76104a0366004613954565b6000908152600660205260409020546001600160401b031690565b6104ce6104c9366004613954565b61232f565b6040516101fb9190613dd3565b7f0000000000000000000000000000000000000000000000000000000000000000610362565b60008061050d836105df565b905060008160048111156105235761052361396d565b14806105405750600181600481111561053e5761053e61396d565b145b1561056c575050600090815260116020526040902060020154600160801b90046001600160401b031690565b60028160048111156105805761058061396d565b036105ac575050600090815260116020526040902060020154600160c01b90046001600160401b031690565b6000838152601160205260409020600201546105d890600160801b90046001600160401b031642612545565b9392505050565b60008181526010602052604081205482906001600160a01b031661061657604051635eeb253d60e11b815260040160405180910390fd5b600083815260116020526040812090815460ff16600481111561063b5761063b61396d565b14801561067a5750600084815260116020526040902060020154600160c01b90046001600160401b03166001600160401b0316426001600160401b0316115b156106895760029250506106fc565b6001815460ff1660048111156106a1576106a161396d565b14806106c257506000815460ff1660048111156106c0576106c061396d565b145b80156106e6575060028101546001600160401b03600160801b909104811642909116115b156106f55760039250506106fc565b5460ff1691505b50919050565b826000808281526012602052604090205460ff1660068111156107275761072761396d565b0361074557604051638b41ec7f60e01b815260040160405180910390fd5b600084815260126020526040902060048101546001600160a01b03163314610799576040517f57a6f4e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107a486611b6d565b905060048160068111156107ba576107ba61396d565b036107f1576040517fc2cbf77700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028160068111156108055761080561396d565b0361081f5761081a8260010154878787612555565b61088d565b60058160068111156108335761083361396d565b036108485761081a826001015487878761279e565b600381600681111561085c5761085c61396d565b0361086b5761081a33876129e7565b600181600681111561087f5761087f61396d565b0361088d5761088d86612a09565b505050505050565b61089f82826120cf565b6108d5576040517f424a04ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006108e18383612c59565b60008181526020819052604090209091506108fc9033612c9e565b50600154600082815260208190526040902060ff9091169061091d90612cb3565b03610961576040516001600160401b038316815283907fc8e6c955744189a19222ec226b72ac1435d88d5745252dac56e6f679f64c037a9060200160405180910390a25b505050565b60008381526010602052604090205483906001600160a01b031661099d57604051635eeb253d60e11b815260040160405180910390fd5b600084815260106020526040902060048101546001600160401b03908116908516106109f5576040517f3b920b8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a018686612c59565b6000818152602081905260409020909150610a1c9033612cbd565b610a52576040517fd651ce1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152601260209081526040808320600181018a90556002810180546fffffffffffffffff00000000000000001916600160401b6001600160401b038c1602179055898452601190925282209091610aab84611b6d565b6006811115610abc57610abc61396d565b14158015610ae457506006610ad084611b6d565b6006811115610ae157610ae161396d565b14155b15610b1b576040517fff556acf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048201805473ffffffffffffffffffffffffffffffffffffffff1916331790556002820180546001600160401b03421667ffffffffffffffff19909116179055610b8c83600090815260056020526040902080546001600160401b03421667ffffffffffffffff19909116179055565b610b9683876121b6565b60028101805460019190600090610bb79084906001600160401b0316613dfc565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610bfc888360020160009054906101000a90046001600160401b0316612cdf565b816001016000828254610c0f9190613e1b565b90915550506040805160e081018252600186015481526002860154602082015260038601549181019190915260048501546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c08201526000908190610c8890612d0e565b90506006610c9586611b6d565b6006811115610ca657610ca661396d565b03610cd957600b54606490610cbe9060ff1683613e2e565b610cc89190613e5b565b610cd29082613e1b565b9150610cdd565b8091505b610ce73383612d2d565b8160136000016000828254610cfc9190613e6f565b9091555050600384018190556004840154610d20906001600160a01b031686612e01565b835460ff191660011784556040516001600160401b038a1681528a907f8f301470a994578b52323d625dfbf827ca5208c81747d3459be7b8867baec3ec9060200160405180910390a2600486015460028401546001600160401b039081169116148015610da257506000835460ff166004811115610da057610da061396d565b145b15610e0c57825460ff191660011783556002830180546001600160401b034216600160401b026fffffffffffffffff0000000000000000199091161790556040518a907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a25b50505050505050505050565b816001610e2482611b6d565b6006811115610e3557610e3561396d565b14610e535760405163ae9dcffd60e01b815260040160405180910390fd5b610e5d8383612e23565b6000838152601260209081526040808320600180820154855260108452828520600b54845160e08101865292820154835260028201549583019590955260038101549382019390935260048301546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0820152909391926064916201000090910460ff1690610f0090612d0e565b610f0a9190613e2e565b610f149190613e5b565b600b54909150600090606490610f34906301000000900460ff1684613e2e565b610f3e9190613e5b565b90508060136001016000828254610f559190613e6f565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015610fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610feb9190613e82565b61100857604051637c2ccffd60e11b815260040160405180910390fd5b8184600301600082825461101c9190613e1b565b9091555050600b5460008881526006602052604090205461010090910460ff16906001600160401b03166001600160401b03161061105d5761105d87612a09565b50505050505050565b600061107982611074612ea6565b612eb1565b92915050565b60006110798261108d612ea6565b612ec5565b60008181526012602090815260408083206001810154845260109092528220600c54610100906110cc90600160801b900460ff1682613ea4565b60018301546110df9161ffff1690613e2e565b6110e99190613e5b565b949350505050565b336000908152600a602052604090206060906111139061111090612f57565b90565b905090565b6111206138de565b604080516101008082018352600b805460ff8082166080808701918252948304821660a080880191909152620100008404831660c08801526301000000909304821660e0870152855285519182018652600c80546001600160401b038082168552600160401b820416602085810191909152600160801b82048416988501989098527101000000000000000000000000000000000090049091166060830152600d80549596939593870194929391928401916111db90613ebe565b80601f016020809104026020016040519081016040528092919081815260200182805461120790613ebe565b80156112545780601f1061122957610100808354040283529160200191611254565b820191906000526020600020905b81548152906001019060200180831161123757829003601f168201915b5050509190925250505081526040805160208181018352600385015460ff1682528301526004909201546001600160401b0316910152919050565b6112998133611c4e565b50565b3360009081526009602052604090206060906111139061111090612f57565b60006112ce6112c98361404f565b612f64565b9050336112de6020840184614158565b6001600160a01b031614611305576040516334c69e3160e11b815260040160405180910390fd5b6000818152601060205260409020546001600160a01b031615611354576040517ffc7d069000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61136661014083016101208401614175565b6001600160401b031615806113ad575061138660e0830160c08401614175565b6001600160401b03166113a161014084016101208501614175565b6001600160401b031610155b156113e4576040517fdf63f61a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113f460a0830160808401614175565b6001600160401b0316600003611436576040517f535ed2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144660a0830160808401614175565b6001600160401b0316611460610100840160e08501614175565b6001600160401b031611156114a1576040517fb9551ab100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114b160e0830160c08401614175565b6001600160401b03166000036114f3576040517f090a5ecd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020820135600003611531576040517f6aba7aae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606082013560000361156f576040517ffb7df0c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201356000036115ad576040517f47ba51c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115bb610100830183614192565b6115c590806141b2565b9050600003611600576040517f86f8cf9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f546001600160401b031661161c60e0840160c08501614175565b6001600160401b0316111561165d576040517f1267b3f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260106020526040902082906116778282614352565b5061168a905060e0830160c08401614175565b6116949042613dfc565b600082815260116020526040902060020180546001600160401b0392909216600160801b0267ffffffffffffffff60801b199092169190911790556116e161014083016101208401614175565b6116eb9042613dfc565b600082815260116020908152604090912060020180546001600160401b0393909316600160c01b0277ffffffffffffffffffffffffffffffffffffffffffffffff9093169290921790915561174c9061174690840184614158565b82612f94565b600061175f61175a8461404f565b612fb6565b600083815260116020526040812060010182905560138054929350839290919061178a908490613e6f565b9091555061179a90503382612d2d565b6000828152601160209081526040918290206002015491517f1bf9c457accf8703dbf7cdf1b58c2f74ddf2e525f98155c70b3d318d74609bd8926117f492869290880191600160c01b90046001600160401b031690614506565b60405180910390a1505050565b806000808281526012602052604090205460ff1660068111156118265761182661396d565b0361184457604051638b41ec7f60e01b815260040160405180910390fd5b61184f823333610702565b5050565b600080600061186984611864612ea6565b612ff2565b90925090508180156110e95750600254600160801b900460ff9081169116109392505050565b61191260405180604001604052806139476040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b60008281526012602052604081205460ff1660068111156119355761193561396d565b0361195357604051638b41ec7f60e01b815260040160405180910390fd5b60008281526012602052604090206119e460405180604001604052806139476040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b600180830154600090815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e08101865295830154865260028301548685015260038301548686015260048301546001600160401b038082166060890152600160401b820481166080890152600160801b8204811692880192909252600160c01b90041660c0860152918201939093528151808301835260058401805492949385019282908290611a9990613ebe565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac590613ebe565b8015611b125780601f10611ae757610100808354040283529160200191611b12565b820191906000526020600020905b815481529060010190602001808311611af557829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0390811683830152600890930154604090920191909152918352600290930154600160401b90049092169181019190915292915050565b600081815260126020526040812060018101548203611b8f5750600092915050565b6000611b9e82600101546105df565b90506004825460ff166006811115611bb857611bb861396d565b03611bc7575060049392505050565b6002816004811115611bdb57611bdb61396d565b03611bea575060059392505050565b6003816004811115611bfe57611bfe61396d565b03611c0d575060029392505050565b6004816004811115611c2157611c2161396d565b03611c30575060039392505050565b505460ff1692915050565b600061107982611c49612ea6565b6130aa565b60008281526010602052604090205482906001600160a01b0316611c8557604051635eeb253d60e11b815260040160405180910390fd5b6000838152601060209081526040808320601190925290912081546001600160a01b03163314611cc8576040516334c69e3160e11b815260040160405180910390fd5b6000611cd3866105df565b90506002816004811115611ce957611ce961396d565b14158015611d0957506004816004811115611d0657611d0661396d565b14155b8015611d2757506003816004811115611d2457611d2461396d565b14155b15611d5e576040517fc00b5b5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003611d9c576040517fbd8bdd9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002816004811115611db057611db061396d565b03611e4e57815460ff1916600217825560405186907ff903f4774c7bd27355f9d7fcbc382b079b164a697a44ac5d95267a4c3cb3bb2290600090a2600086815260116020526040902060020154611e18908790600160c01b90046001600160401b0316612cdf565b6002830154611e3091906001600160401b0316613e2e565b826001016000828254611e439190613e6f565b90915550611fdb9050565b6004816004811115611e6257611e6261396d565b03611fcf576040805160a0808201835285546001600160a01b03168252825160e08101845260018701548152600287015460208281019190915260038801548286015260048801546001600160401b038082166060850152600160401b820481166080850152600160801b8204811694840194909452600160c01b900490921660c08201529082015281518083018352600586018054611fc594889390850192909182908290611f1190613ebe565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3d90613ebe565b8015611f8a5780601f10611f5f57610100808354040283529160200191611f8a565b820191906000526020600020905b815481529060010190602001808311611f6d57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b031690820152600890910154604090910152612fb6565b6001830155611fdb565b815460ff191660031782555b8254611ff0906001600160a01b0316876130e4565b60018201546014805482919060009061200a908490613e6f565b909155505060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561207e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a29190613e82565b6120bf57604051637c2ccffd60e11b815260040160405180910390fd5b5050600060019091015550505050565b600033816120dd8585612c59565b905060006120ea82611b6d565b905060008160068111156121005761210061396d565b148061211d5750600681600681111561211b5761211b61396d565b145b80156121465750600154600083815260208190526040902060ff9091169061214490612cb3565b105b8015612167575060008281526020819052604090206121659084612cbd565b155b9695505050505050565b81600161217d82611b6d565b600681111561218e5761218e61396d565b146121ac5760405163ae9dcffd60e01b815260040160405180910390fd5b6109618383613106565b6000828152601260209081526040808320600101548084526010909252909120546001600160a01b03166121fd57604051635eeb253d60e11b815260040160405180910390fd5b600083815260126020526040902060048101546001600160a01b03163314612251576040517fce351b9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001810154600090815260106020526040808220815160038082526080820190935290929181602001602082028036833701905050905061229961229487611066565b6132a3565b816000815181106122ac576122ac6145b3565b602090810291909101015260068201546122c5906132b4565b816001815181106122d8576122d86145b3565b6020026020010181815250508260020160089054906101000a90046001600160401b03166001600160401b031681600281518110612318576123186145b3565b60200260200101818152505061088d8686836132c0565b6123a46040805160a080820183526000808352835160e081018552818152602080820183905281860183905260608083018490526080830184905293820183905260c0820183905280850191909152845180860186529283528201529091820190815260006020820181905260409091015290565b60008281526010602052604090205482906001600160a01b03166123db57604051635eeb253d60e11b815260040160405180910390fd5b600083815260106020908152604091829020825160a0808201855282546001600160a01b03168252845160e0810186526001840154815260028401548186015260038401548187015260048401546001600160401b038082166060840152600160401b820481166080840152600160801b8204811693830193909352600160c01b900490911660c0820152928101929092528251808401845260058201805493949293928501928290829061248f90613ebe565b80601f01602080910402602001604051908101604052809291908181526020018280546124bb90613ebe565b80156125085780601f106124dd57610100808354040283529160200191612508565b820191906000526020600020905b8154815290600101906020018083116124eb57829003601f168201915b50505091835250506001919091015460209182015290825260078301546001600160401b0316908201526008909101546040909101529392505050565b60008282188284100282186105d8565b60008481526010602052604090205484906001600160a01b031661258c57604051635eeb253d60e11b815260040160405180910390fd5b600085815260116020908152604080832060108352818420815460ff191660031782558885526012909352922081546125ce906001600160a01b0316896130e4565b60048101546125e6906001600160a01b0316886129e7565b6002810154600090612602908a906001600160401b0316612cdf565b60038301549091506126148183613e6f565b60148054600090612626908490613e6f565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038981166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156126ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d19190613e82565b6126ee57604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038881166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561275d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127819190613e82565b610e0c57604051637c2ccffd60e11b815260040160405180910390fd5b60008481526010602052604090205484906001600160a01b03166127d557604051635eeb253d60e11b815260040160405180910390fd5b600084815260126020526040902060048101546127fb906001600160a01b0316866129e7565b60028101546000906128419088906001600160401b031661283c826000908152601160205260409020600201546001600160401b03600160c01b9091041690565b61345e565b60038301549091506128538183613e6f565b60148054600090612865908490613e6f565b90915550508254600490849060ff1916600183021790555060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156128ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129109190613e82565b61292d57604051637c2ccffd60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561299c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c09190613e82565b6129dd57604051637c2ccffd60e11b815260040160405180910390fd5b5050505050505050565b6001600160a01b0382166000908152600a60205260409020610961908261353d565b60008181526012602090815260408083206001810154808552601190935292206002830154612a429083906001600160401b0316612cdf565b816001016000828254612a559190613e6f565b90915550506004830154612a72906001600160a01b0316856129e7565b6000848152602081905260409020612a8990613549565b825460ff191660061783556002808401805467ffffffffffffffff1916905560006003850181905560048501805473ffffffffffffffffffffffffffffffffffffffff19169055908201805460019290612aed9084906001600160401b03166145c9565b82546101009290920a6001600160401b038181021990931691831602179091556002850154604051600160401b90910490911681528391507f33ba8f7627565d89f7ada2a6b81ea532b7aa9b11e91a78312d6e1fca0bfcd1dc9060200160405180910390a26000848152600660205260409020805467ffffffffffffffff19169055600082815260106020526040812060028301546004820154919291612ba0916001600160401b0390811691166145c9565b60048301546001600160401b039182169250600160c01b90041681118015612bdd57506001835460ff166004811115612bdb57612bdb61396d565b145b1561088d57825460ff19166004178355612bf86001426145c9565b6002840180546001600160401b0392909216600160801b0267ffffffffffffffff60801b1990921691909117905560405184907f4769361a442504ecaf038f35e119bcccdd5e42096b24c09e3c17fd17c6684c0290600090a2505050505050565b60008282604051602001612c809291909182526001600160401b0316602082015260400190565b60405160208183030381529060405280519060200120905092915050565b60006105d8836001600160a01b038416613552565b6000611079825490565b6001600160a01b038116600090815260018301602052604081205415156105d8565b6000828152601160205260408120600201546105d89084908490600160801b90046001600160401b031661345e565b600081608001516001600160401b031682604001516110799190613e2e565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152306024830181905260448301849052917f0000000000000000000000000000000000000000000000000000000000000000909116906323b872dd906064016020604051808303816000875af1158015612dc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de49190613e82565b61096157604051637c2ccffd60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600a6020526040902061096190826135a1565b612e2d8282613106565b60008281526008602090815260408083206001600160401b038086168552908352818420805460ff1916600190811790915586855260069093529083208054929390929091612e7e91859116613dfc565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505050565b6000611113426135ad565b60006105d8612ec08484612ec5565b6135d9565b600080612ed4610100436145e8565b60025490915060009061010090612f039071010000000000000000000000000000000000900460ff16866145fc565b612f0d919061461e565b6001600160401b031690506000612f26610100876145e8565b9050600061010082612f388587613e6f565b612f429190613e6f565b612f4c91906145e8565b979650505050505050565b606060006105d883613633565b600081604051602001612f779190613dd3565b604051602081830303815290604052805190602001209050919050565b6001600160a01b038216600090815260096020526040902061096190826135a1565b6000612fc5826020015161368f565b602083015160a0810151606090910151612fdf91906145fc565b6001600160401b03166110799190613e2e565b600080600061300085611b6d565b60008681526005602052604081205491925090613025906001600160401b03166135ad565b9050600182600681111561303b5761303b61396d565b14158061304f575061304d85826136ae565b155b15613062576000809350935050506130a3565b61306c8686612ec5565b92506000613079846135d9565b9050600061308688611092565b905080158061309c575061309a81836145e8565b155b9550505050505b9250929050565b60008060006130b98585612ff2565b90925090508180156130db575060025460ff600160801b909104811690821610155b95945050505050565b6001600160a01b0382166000908152600960205260409020610961908261353d565b6000613111826136c4565b6001600160401b03169050428110613155576040517f6b4b1a4e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025461317290600160401b90046001600160401b031682613e6f565b42106131aa576040517fde55698e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602090815260408083206001600160401b038616845290915290205460ff1615613206576040517efab7d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61321083836130aa565b613246576040517fd3ffa66b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260408083206001600160401b038616845290915290205460ff1615610961576040517f98e7e55100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060ff198216816110e9826136d7565b6000806105d8836136d7565b6000838152600760205260408120906132d7612ea6565b6001600160401b0316815260208101919091526040016000205460ff161561332b576040517f3edef7db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546040517f94c8919d0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116916394c8919d9161337591869186910161464c565b602060405180830381865afa158015613392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b69190613e82565b6133ec576040517ffcd03a4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260408120600191613405612ea6565b6001600160401b031681526020808201929092526040908101600020805460ff19169315159390931790925590518481527f3b989d183b84b02259d7c14b34a9c9eb0fccb4c355a920d25e581e25aef4993d91016117f4565b60008381526010602052604081206001600160401b03808416908516106134b1576040517f56607cb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600183015481526002830154602082015260038301549181019190915260048201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c08201526135209061368f565b61352a85856145c9565b6001600160401b03166130db9190613e2e565b60006105d88383613749565b61129981613843565b600081815260018301602052604081205461359957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611079565b506000611079565b60006105d88383613552565b60006110797f0000000000000000000000000000000000000000000000000000000000000000836146f6565b60008060ff83166135eb600143613e1b565b6135f59190613e1b565b409050600081900361360957613609614724565b60408051602081018390520160405160208183030381529060405280519060200120915050919050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561368357602002820191906000526020600020905b81548152602001906001019080831161366f575b50505050509050919050565b600081608001516001600160401b031682602001516110799190613e2e565b60006001600160401b03808416908316106105d8565b60006110796136d2836138a5565b6138b2565b7fff00000000000000000000000000000000000000000000000000000000000000811660015b60208110156106fc57600891821c91613717908290613e2e565b83901b7fff000000000000000000000000000000000000000000000000000000000000001691909117906001016136fd565b6000818152600183016020526040812054801561383257600061376d600183613e1b565b855490915060009061378190600190613e1b565b90508082146137e65760008660000182815481106137a1576137a16145b3565b90600052602060002001549050808760000184815481106137c4576137c46145b3565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806137f7576137f761473a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611079565b6000915050611079565b5092915050565b600061384d825490565b905060005b8181101561389d57826001016000846000018381548110613875576138756145b3565b9060005260206000200154815260200190815260200160002060009055806001019050613852565b505060009055565b6000611079826001613dfc565b60006110797f0000000000000000000000000000000000000000000000000000000000000000836145fc565b60408051610100810182526000608080830182815260a080850184905260c0850184905260e08501849052908452845190810185528281526020808201849052818601849052606080830185905292820192909252818401528351908101845290815290918201905b8152600060209091015290565b60006020828403121561396657600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60208101600583106139975761399761396d565b91905290565b6001600160a01b038116811461129957600080fd5b6000806000606084860312156139c757600080fd5b8335925060208401356139d98161399d565b915060408401356139e98161399d565b809150509250925092565b6001600160401b038116811461129957600080fd5b8035613a14816139f4565b919050565b60008060408385031215613a2c57600080fd5b823591506020830135613a3e816139f4565b809150509250929050565b600061010082840312156106fc57600080fd5b60008060006101408486031215613a7257600080fd5b833592506020840135613a84816139f4565b9150613a938560408601613a49565b90509250925092565b602080825282518282018190526000918401906040840190835b81811015613ad4578351835260209384019390920191600101613ab6565b509095945050505050565b6000815180845260005b81811015613b0557602081850181015186830182015201613ae9565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160401b0381511682526001600160401b03602082015116602083015260ff604082015116604083015260ff60608201511660608301526000608082015160a060808501526110e960a0850182613adf565b602081526000825160ff815116602084015260ff602082015116604084015260ff604082015116606084015260ff606082015116608084015250602083015160e060a0840152613bce610100840182613b25565b90506040840151613be560c08501825160ff169052565b5060608401516001600160401b03811660e0850152509392505050565b600060208284031215613c1457600080fd5b81356001600160401b03811115613c2a57600080fd5b820161016081850312156105d857600080fd5b6000815160408452613c526040850182613adf565b602093840151949093019390935250919050565b6001600160a01b038151168252600060208201518051602085015260208101516040850152604081015160608501526001600160401b0360608201511660808501526001600160401b0360808201511660a08501526001600160401b0360a08201511660c08501526001600160401b0360c08201511660e0850152506040820151610160610100850152613cfe610160850182613c3d565b90506060830151613d1b6101208601826001600160401b03169052565b5060808301516101408501528091505092915050565b602081526000825160406020840152613d4d6060840182613c66565b90506001600160401b0360208501511660408401528091505092915050565b60208101600783106139975761399761396d565b60008060408385031215613d9357600080fd5b823591506020830135613a3e8161399d565b6000806101208385031215613db957600080fd5b82359150613dca8460208501613a49565b90509250929050565b6020815260006105d86020830184613c66565b634e487b7160e01b600052601160045260246000fd5b6001600160401b03818116838216019081111561107957611079613de6565b8181038181111561107957611079613de6565b808202811582820484141761107957611079613de6565b634e487b7160e01b600052601260045260246000fd5b600082613e6a57613e6a613e45565b500490565b8082018082111561107957611079613de6565b600060208284031215613e9457600080fd5b815180151581146105d857600080fd5b61ffff828116828216039081111561107957611079613de6565b600181811c90821680613ed257607f821691505b6020821081036106fc57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613f2a57613f2a613ef2565b60405290565b60405160a081016001600160401b0381118282101715613f2a57613f2a613ef2565b60405160e081016001600160401b0381118282101715613f2a57613f2a613ef2565b604051601f8201601f191681016001600160401b0381118282101715613f9c57613f9c613ef2565b604052919050565b600060408284031215613fb657600080fd5b613fbe613f08565b905081356001600160401b03811115613fd657600080fd5b8201601f81018413613fe757600080fd5b80356001600160401b0381111561400057614000613ef2565b614013601f8201601f1916602001613f74565b81815285602083850101111561402857600080fd5b81602084016020830137600060209282018301528352928301359282019290925292915050565b600081360361016081121561406357600080fd5b61406b613f30565b83356140768161399d565b815260e0601f198301121561408a57600080fd5b614092613f52565b602085810135825260408087013591830191909152606086013590820152915060808401356140c0816139f4565b606083015260a08401356140d3816139f4565b608083015260c08401356140e6816139f4565b60a083015260e08401356140f9816139f4565b60c08301526020810191909152610100830135906001600160401b0382111561412157600080fd5b61412d36838601613fa4565b604082015261413f6101208501613a09565b6060820152610140939093013560808401525090919050565b60006020828403121561416a57600080fd5b81356105d88161399d565b60006020828403121561418757600080fd5b81356105d8816139f4565b60008235603e198336030181126141a857600080fd5b9190910192915050565b6000808335601e198436030181126141c957600080fd5b8301803591506001600160401b038211156141e357600080fd5b6020019150368190038213156130a357600080fd5b60008135611079816139f4565b601f82111561096157806000526020600020601f840160051c8101602085101561422c5750805b601f840160051c820191505b8181101561424c5760008155600101614238565b5050505050565b8135601e1983360301811261426757600080fd5b820180356001600160401b038111801561428057600080fd5b81360360208401131561429257600080fd5b600090506142aa826142a48654613ebe565b86614205565b80601f8311600181146142df578284156142c75750848201602001355b600019600386901b1c1916600185901b17865561433e565b600086815260209020601f19851690845b82811015614312576020858901810135835594850194600190920191016142f0565b50858210156143325760001960f88760031b161c19602085890101351681555b505060018460011b0186555b505050505060209190910135600190910155565b813561435d8161399d565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03919091161781556020820135600182015560408201356002820155606082013560038201556004810160808301356143b5816139f4565b815467ffffffffffffffff19166001600160401b0382161782555060a08301356143de816139f4565b81546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff00000000000000001617815561445261441d60c085016141f8565b825467ffffffffffffffff60801b191660809190911b77ffffffffffffffff0000000000000000000000000000000016178255565b6144aa61446160e085016141f8565b825477ffffffffffffffffffffffffffffffffffffffffffffffff1660c09190911b7fffffffffffffffff00000000000000000000000000000000000000000000000016178255565b506144c56144bc610100840184614192565b60058301614253565b6144f66144d561012084016141f8565b600783016001600160401b0382166001600160401b03198254161781555050565b6101409190910135600890910155565b838152823560208083019190915283013560408083019190915283013560608083019190915261012082019084013561453e816139f4565b6001600160401b038116608084015250608084013561455c816139f4565b6001600160401b03811660a08401525060a084013561457a816139f4565b6001600160401b03811660c08401525061459660c08501613a09565b6001600160401b0390811660e084015283166101008301526110e9565b634e487b7160e01b600052603260045260246000fd5b6001600160401b03828116828216039081111561107957611079613de6565b6000826145f7576145f7613e45565b500690565b6001600160401b03818116838216029081169081811461383c5761383c613de6565b60006001600160401b0383168061463757614637613e45565b806001600160401b0384160691505092915050565b82358152602080840135908201526000610120820161467b604084016040870180358252602090810135910152565b614695608084016080870180358252602090810135910152565b6146af60c0840160c0870180358252602090810135910152565b610120610100840152835190819052602084019061014084019060005b818110156146ea5783518352602093840193909201916001016146cc565b50909695505050505050565b60006001600160401b0383168061470f5761470f613e45565b806001600160401b0384160491505092915050565b634e487b7160e01b600052600160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212206dff77c91b35d52a507921036c4f144a6da81a73042b293f820f8cf1bc1728f264736f6c634300081c0033"; public MarketplaceDeploymentBase() : base(BYTECODE) { } public MarketplaceDeploymentBase(string byteCode) : base(byteCode) { } [Parameter("tuple", "config", 1)] diff --git a/ProjectPlugins/CodexPlugin/CodexDockerImage.cs b/ProjectPlugins/CodexPlugin/CodexDockerImage.cs index 4979f561..c7f0f35b 100644 --- a/ProjectPlugins/CodexPlugin/CodexDockerImage.cs +++ b/ProjectPlugins/CodexPlugin/CodexDockerImage.cs @@ -2,7 +2,7 @@ { public class CodexDockerImage { - private const string DefaultDockerImage = "codexstorage/nim-codex:sha-3e17207-dist-tests"; + private const string DefaultDockerImage = "codexstorage/nim-codex:sha-e324ac8-dist-tests"; public static string Override { get; set; } = string.Empty; diff --git a/Tests/CodexReleaseTests/DataTests/DecodeTest.cs b/Tests/CodexReleaseTests/DataTests/DecodeTest.cs index 1aaf742f..0720ff10 100644 --- a/Tests/CodexReleaseTests/DataTests/DecodeTest.cs +++ b/Tests/CodexReleaseTests/DataTests/DecodeTest.cs @@ -1,6 +1,4 @@ -using System.Security.Cryptography; -using CodexReleaseTests.Utils; -using Nethereum.JsonRpc.Client; +using CodexReleaseTests.Utils; using NUnit.Framework; using Utils; diff --git a/Tests/DistTestCore/DistTest.cs b/Tests/DistTestCore/DistTest.cs index 4c6cb0af..21053f57 100644 --- a/Tests/DistTestCore/DistTest.cs +++ b/Tests/DistTestCore/DistTest.cs @@ -179,16 +179,34 @@ namespace DistTestCore private IWebCallTimeSet GetWebCallTimeSet() { + if (IsRunningInCluster()) + { + Log(" > Detected we're running in the cluster. Using long webCall timeset."); + return new LongWebCallTimeSet(); + } + if (ShouldUseLongTimeouts()) return new LongWebCallTimeSet(); return new DefaultWebCallTimeSet(); } private IK8sTimeSet GetK8sTimeSet() { + if (IsRunningInCluster()) + { + Log(" > Detected we're running in the cluster. Using long kubernetes timeset."); + return new LongK8sTimeSet(); + } + if (ShouldUseLongTimeouts()) return new LongK8sTimeSet(); return new DefaultK8sTimeSet(); } + private bool IsRunningInCluster() + { + var testType = Environment.GetEnvironmentVariable("TEST_TYPE"); + return testType == "release-tests"; + } + private bool ShouldWaitForCleanup() { return CurrentTestMethodHasAttribute(); @@ -256,7 +274,7 @@ namespace DistTestCore private string GetCurrentTestName() { - return $"[{TestContext.CurrentContext.Test.Name}]"; + return $"[{NameUtils.GetTestMethodName()}]"; } public DistTestResult GetTestResult() diff --git a/Tools/BiblioTech/AdminChecker.cs b/Tools/BiblioTech/AdminChecker.cs index 96f89691..5c7ff103 100644 --- a/Tools/BiblioTech/AdminChecker.cs +++ b/Tools/BiblioTech/AdminChecker.cs @@ -35,6 +35,7 @@ namespace BiblioTech public async Task SendInAdminChannel(string[] lines) { + if (adminChannel == null) return; var chunker = new LineChunker(lines); var chunks = chunker.GetChunks(); if (!chunks.Any()) return; diff --git a/Tools/BiblioTech/BaseCommand.cs b/Tools/BiblioTech/BaseCommand.cs index eb411dd2..83e30f26 100644 --- a/Tools/BiblioTech/BaseCommand.cs +++ b/Tools/BiblioTech/BaseCommand.cs @@ -20,7 +20,9 @@ namespace BiblioTech Program.Log.Log($"Responding to '{Name}'"); var context = new CommandContext(command, command.Data.Options); await command.RespondAsync(StartingMessage, ephemeral: IsEphemeral(context)); - await Invoke(context); + + // Fire and forget invocation handler. Return SlashCommandHandler immediately. + _ = Invoke(context); } catch (Exception ex) { diff --git a/Tools/BiblioTech/BaseGethCommand.cs b/Tools/BiblioTech/BaseGethCommand.cs index 49069953..104784cc 100644 --- a/Tools/BiblioTech/BaseGethCommand.cs +++ b/Tools/BiblioTech/BaseGethCommand.cs @@ -8,9 +8,13 @@ namespace BiblioTech { protected override async Task Invoke(CommandContext context) { - var gethConnector = GethConnector.GethConnector.Initialize(Program.Log); + var gethConnector = GetGeth(); + if (gethConnector == null) + { + await context.Followup("Blockchain operations are (temporarily) unavailable."); + return; + } - if (gethConnector == null) return; var gethNode = gethConnector.GethNode; var contracts = gethConnector.CodexContracts; @@ -23,6 +27,19 @@ namespace BiblioTech await Execute(context, gethNode, contracts); } + private GethConnector.GethConnector? GetGeth() + { + try + { + return GethConnector.GethConnector.Initialize(Program.Log); + } + catch (Exception ex) + { + Program.Log.Error("Failed to initialize geth connector: " + ex); + return null; + } + } + protected abstract Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts); } } diff --git a/Tools/BiblioTech/CodexChecking/CheckRepo.cs b/Tools/BiblioTech/CodexChecking/CheckRepo.cs index a8b2860b..a02e44b7 100644 --- a/Tools/BiblioTech/CodexChecking/CheckRepo.cs +++ b/Tools/BiblioTech/CodexChecking/CheckRepo.cs @@ -1,16 +1,20 @@ -using Newtonsoft.Json; +using Logging; +using Newtonsoft.Json; +using Utils; namespace BiblioTech.CodexChecking { public class CheckRepo { private const string modelFilename = "model.json"; + private readonly ILog log; private readonly Configuration config; private readonly object _lock = new object(); private CheckRepoModel? model = null; - public CheckRepo(Configuration config) + public CheckRepo(ILog log, Configuration config) { + this.log = log; this.config = config; } @@ -18,20 +22,32 @@ namespace BiblioTech.CodexChecking { lock (_lock) { - if (model == null) LoadModel(); - - var existing = model.Reports.SingleOrDefault(r => r.UserId == userId); - if (existing == null) + var sw = System.Diagnostics.Stopwatch.StartNew(); + try { - var newEntry = new CheckReport + if (model == null) LoadModel(); + + var existing = model.Reports.SingleOrDefault(r => r.UserId == userId); + if (existing == null) { - UserId = userId, - }; - model.Reports.Add(newEntry); - SaveChanges(); - return newEntry; + var newEntry = new CheckReport + { + UserId = userId, + }; + model.Reports.Add(newEntry); + SaveChanges(); + return newEntry; + } + return existing; + } + finally + { + var elapsed = sw.Elapsed; + if (elapsed > TimeSpan.FromMilliseconds(500)) + { + log.Log($"Warning {nameof(GetOrCreate)} took {Time.FormatDuration(elapsed)}"); + } } - return existing; } } diff --git a/Tools/BiblioTech/CodexChecking/CodexTwoWayChecker.cs b/Tools/BiblioTech/CodexChecking/CodexTwoWayChecker.cs index 1dc6b681..6fb2f28e 100644 --- a/Tools/BiblioTech/CodexChecking/CodexTwoWayChecker.cs +++ b/Tools/BiblioTech/CodexChecking/CodexTwoWayChecker.cs @@ -15,6 +15,7 @@ namespace BiblioTech.CodexChecking Task CouldNotDownloadCid(); Task GiveCidToUser(string cid); Task GiveDataFileToUser(string fileContent); + Task CodexUnavailable(); Task ToAdminChannel(string msg); } @@ -44,6 +45,12 @@ namespace BiblioTech.CodexChecking } var cid = UploadData(check.UniqueData); + if (cid == null) + { + await handler.CodexUnavailable(); + return; + } + await handler.GiveCidToUser(cid); } @@ -96,7 +103,12 @@ namespace BiblioTech.CodexChecking if (IsManifestLengthCompatible(handler, check, manifest)) { - if (IsContentCorrect(handler, check, receivedCid)) + var correct = IsContentCorrect(handler, check, receivedCid); + if (!correct.HasValue) { + await handler.CodexUnavailable(); + return; + } + if (correct.Value) { await CheckNowCompleted(handler, check, userId, "UploadCheck"); return; @@ -120,7 +132,7 @@ namespace BiblioTech.CodexChecking check.CompletedUtc < expiry; } - private string UploadData(string uniqueData) + private string? UploadData(string uniqueData) { var filePath = Path.Combine(config.ChecksDataPath, Guid.NewGuid().ToString()); @@ -172,7 +184,7 @@ namespace BiblioTech.CodexChecking manifestLength < (dataLength + 1); } - private bool IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid) + private bool? IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid) { try { @@ -190,6 +202,8 @@ namespace BiblioTech.CodexChecking } }); + if (content == null) return null; + Log($"Checking content: content={content},check={check.UniqueData}"); return content == check.UniqueData; } diff --git a/Tools/BiblioTech/CodexChecking/CodexWrapper.cs b/Tools/BiblioTech/CodexChecking/CodexWrapper.cs index 3c295d7f..f1f35822 100644 --- a/Tools/BiblioTech/CodexChecking/CodexWrapper.cs +++ b/Tools/BiblioTech/CodexChecking/CodexWrapper.cs @@ -21,32 +21,72 @@ namespace BiblioTech.CodexChecking var httpFactory = CreateHttpFactory(); factory = new CodexNodeFactory(log, httpFactory, dataDir: config.DataPath); + + Task.Run(CheckCodexNode); } - public void OnCodex(Action action) + public T? OnCodex(Func func) where T : class { lock (codexLock) { - action(Get()); + if (currentCodexNode == null) return null; + return func(currentCodexNode); } } - public T OnCodex(Func func) + private void CheckCodexNode() { - lock (codexLock) + Thread.Sleep(TimeSpan.FromSeconds(10.0)); + + while (true) { - return func(Get()); + lock (codexLock) + { + var newNode = GetNewCodexNode(); + if (newNode != null && currentCodexNode == null) ShowConnectionRestored(); + if (newNode == null && currentCodexNode != null) ShowConnectionLost(); + currentCodexNode = newNode; + } + + Thread.Sleep(TimeSpan.FromMinutes(15.0)); } } - private ICodexNode Get() + private ICodexNode? GetNewCodexNode() { - if (currentCodexNode == null) + try { - currentCodexNode = CreateCodex(); - } + if (currentCodexNode != null) + { + try + { + // Current instance is responsive? Keep it. + var info = currentCodexNode.GetDebugInfo(); + if (info != null && info.Version != null && + !string.IsNullOrEmpty(info.Version.Revision)) return currentCodexNode; + } + catch + { + } + } - return currentCodexNode; + return CreateCodex(); + } + catch (Exception ex) + { + log.Error("Exception when trying to check codex node: " + ex.Message); + return null; + } + } + + private void ShowConnectionLost() + { + Program.AdminChecker.SendInAdminChannel("Codex node connection lost."); + } + + private void ShowConnectionRestored() + { + Program.AdminChecker.SendInAdminChannel("Codex node connection restored."); } private ICodexNode CreateCodex() @@ -70,16 +110,34 @@ namespace BiblioTech.CodexChecking { if (string.IsNullOrEmpty(config.CodexEndpointAuth) || !config.CodexEndpointAuth.Contains(":")) { - return new HttpFactory(log); + return new HttpFactory(log, new SnappyTimeSet()); } var tokens = config.CodexEndpointAuth.Split(':'); if (tokens.Length != 2) throw new Exception("Expected ':' in CodexEndpointAuth parameter."); - return new HttpFactory(log, onClientCreated: client => + return new HttpFactory(log, new SnappyTimeSet(), onClientCreated: client => { client.SetBasicAuthentication(tokens[0], tokens[1]); }); } + + public class SnappyTimeSet : IWebCallTimeSet + { + public TimeSpan HttpCallRetryDelay() + { + return TimeSpan.FromSeconds(1.0); + } + + public TimeSpan HttpCallTimeout() + { + return TimeSpan.FromSeconds(3.0); + } + + public TimeSpan HttpRetryTimeout() + { + return TimeSpan.FromSeconds(12.0); + } + } } } diff --git a/Tools/BiblioTech/Commands/CheckDownloadCommand.cs b/Tools/BiblioTech/Commands/CheckDownloadCommand.cs index 0e1aa563..d2119833 100644 --- a/Tools/BiblioTech/Commands/CheckDownloadCommand.cs +++ b/Tools/BiblioTech/Commands/CheckDownloadCommand.cs @@ -18,7 +18,7 @@ namespace BiblioTech.Commands } public override string Name => "checkdownload"; - public override string StartingMessage => RandomBusyMessage.Get(); + public override string StartingMessage => "Connecting to the testnet... Please be patient... " + RandomBusyMessage.Get(); public override string Description => "Checks the download connectivity of your Codex node."; public override CommandOption[] Options => [contentOption]; diff --git a/Tools/BiblioTech/Commands/CheckResponseHandler.cs b/Tools/BiblioTech/Commands/CheckResponseHandler.cs index f7b1c4f0..c10ef23e 100644 --- a/Tools/BiblioTech/Commands/CheckResponseHandler.cs +++ b/Tools/BiblioTech/Commands/CheckResponseHandler.cs @@ -26,6 +26,11 @@ namespace BiblioTech.Commands await context.Followup("Could not download the CID."); } + public async Task CodexUnavailable() + { + await context.Followup("Couldn't perform check: Our Codex node appears unavailable. Try again later?"); + } + public async Task GiveCidToUser(string cid) { await context.Followup( diff --git a/Tools/BiblioTech/Commands/CheckUploadCommand.cs b/Tools/BiblioTech/Commands/CheckUploadCommand.cs index b1589b5c..51d6d394 100644 --- a/Tools/BiblioTech/Commands/CheckUploadCommand.cs +++ b/Tools/BiblioTech/Commands/CheckUploadCommand.cs @@ -18,7 +18,7 @@ namespace BiblioTech.Commands } public override string Name => "checkupload"; - public override string StartingMessage => RandomBusyMessage.Get(); + public override string StartingMessage => "Connecting to the testnet... Please be patient... " + RandomBusyMessage.Get(); public override string Description => "Checks the upload connectivity of your Codex node."; public override CommandOption[] Options => [cidOption]; diff --git a/Tools/BiblioTech/Program.cs b/Tools/BiblioTech/Program.cs index 0ce84bde..f0d63758 100644 --- a/Tools/BiblioTech/Program.cs +++ b/Tools/BiblioTech/Program.cs @@ -88,7 +88,7 @@ namespace BiblioTech client = new DiscordSocketClient(); client.Log += ClientLog; - var checkRepo = new CheckRepo(Config); + var checkRepo = new CheckRepo(Log, Config); var codexWrapper = new CodexWrapper(Log, Config); var checker = new CodexTwoWayChecker(Log, Config, checkRepo, codexWrapper); var notifyCommand = new NotifyCommand(); diff --git a/Tools/MarketInsights/ContributionBuilder.cs b/Tools/MarketInsights/ContributionBuilder.cs index 50bf48ad..387fd62b 100644 --- a/Tools/MarketInsights/ContributionBuilder.cs +++ b/Tools/MarketInsights/ContributionBuilder.cs @@ -1,6 +1,5 @@ using BlockchainUtils; using CodexContractsPlugin.ChainMonitor; -using GethPlugin; using Logging; using System.Numerics; using Utils; @@ -47,7 +46,7 @@ namespace MarketInsights AddRequestToAverage(segment.Started, requestEvent); } - public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { } diff --git a/Tools/TestNetRewarder/EmojiMaps.cs b/Tools/TestNetRewarder/EmojiMaps.cs index 38684c55..dcde4f97 100644 --- a/Tools/TestNetRewarder/EmojiMaps.cs +++ b/Tools/TestNetRewarder/EmojiMaps.cs @@ -78,6 +78,7 @@ public string NewRequest => "🌱"; public string Started => "🌳"; public string SlotFilled => "🟢"; + public string SlotRepaired => "♻"; public string SlotFreed => "⭕"; public string SlotReservationsFull => "☑️"; public string Finished => "✅"; diff --git a/Tools/TestNetRewarder/EventsFormatter.cs b/Tools/TestNetRewarder/EventsFormatter.cs index 7e363432..b44e476e 100644 --- a/Tools/TestNetRewarder/EventsFormatter.cs +++ b/Tools/TestNetRewarder/EventsFormatter.cs @@ -1,8 +1,7 @@ using BlockchainUtils; -using CodexContractsPlugin; using CodexContractsPlugin.ChainMonitor; +using CodexContractsPlugin.Marketplace; using DiscordRewards; -using GethPlugin; using System.Globalization; using System.Numerics; using Utils; @@ -16,10 +15,12 @@ namespace TestNetRewarder private readonly List errors = new List(); private readonly EmojiMaps emojiMaps = new EmojiMaps(); private readonly Configuration config; + private readonly string periodDuration; - public EventsFormatter(Configuration config) + public EventsFormatter(Configuration config, MarketplaceConfig marketplaceConfig) { this.config = config; + periodDuration = Time.FormatDuration(marketplaceConfig.PeriodDuration); } public ChainEventMessage[] GetInitializationEvents(Configuration config) @@ -49,7 +50,7 @@ namespace TestNetRewarder public void OnNewRequest(RequestEvent requestEvent) { var request = requestEvent.Request; - AddRequestBlock(requestEvent, $"{emojiMaps.NewRequest} New Request", + AddRequestBlock(requestEvent, emojiMaps.NewRequest, "New Request", $"Client: {request.Client}", $"Content: {BytesToHexString(request.Request.Content.Cid)}", $"Duration: {BigIntToDuration(request.Request.Ask.Duration)}", @@ -58,33 +59,34 @@ namespace TestNetRewarder $"PricePerBytePerSecond: {BitIntToTestTokens(request.Request.Ask.PricePerBytePerSecond)}", $"Number of Slots: {request.Request.Ask.Slots}", $"Slot Tolerance: {request.Request.Ask.MaxSlotLoss}", - $"Slot Size: {BigIntToByteSize(request.Request.Ask.SlotSize)}" + $"Slot Size: {BigIntToByteSize(request.Request.Ask.SlotSize)}", + $"Proof Probability: 1 / {request.Request.Ask.ProofProbability} every {periodDuration}" ); } public void OnRequestCancelled(RequestEvent requestEvent) { - AddRequestBlock(requestEvent, $"{emojiMaps.Cancelled} Cancelled"); + AddRequestBlock(requestEvent, emojiMaps.Cancelled, "Cancelled"); } public void OnRequestFailed(RequestEvent requestEvent) { - AddRequestBlock(requestEvent, $"{emojiMaps.Failed} Failed"); + AddRequestBlock(requestEvent, emojiMaps.Failed, "Failed"); } public void OnRequestFinished(RequestEvent requestEvent) { - AddRequestBlock(requestEvent, $"{emojiMaps.Finished} Finished"); + AddRequestBlock(requestEvent, emojiMaps.Finished, "Finished"); } public void OnRequestFulfilled(RequestEvent requestEvent) { - AddRequestBlock(requestEvent, $"{emojiMaps.Started} Started"); + AddRequestBlock(requestEvent, emojiMaps.Started, "Started"); } - public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { - AddRequestBlock(requestEvent, $"{emojiMaps.SlotFilled} Slot Filled", + AddRequestBlock(requestEvent, GetSlotFilledIcon(isRepair), GetSlotFilledTitle(isRepair), $"Host: {host}", $"Slot Index: {slotIndex}" ); @@ -92,14 +94,14 @@ namespace TestNetRewarder public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex) { - AddRequestBlock(requestEvent, $"{emojiMaps.SlotFreed} Slot Freed", + AddRequestBlock(requestEvent, emojiMaps.SlotFreed, "Slot Freed", $"Slot Index: {slotIndex}" ); } public void OnSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex) { - AddRequestBlock(requestEvent, $"{emojiMaps.SlotReservationsFull} Slot Reservations Full", + AddRequestBlock(requestEvent, emojiMaps.SlotReservationsFull, "Slot Reservations Full", $"Slot Index: {slotIndex}" ); } @@ -133,6 +135,18 @@ namespace TestNetRewarder AddBlock(0, $"{emojiMaps.ProofReport} **Proof system report**", lines.ToArray()); } + private string GetSlotFilledIcon(bool isRepair) + { + if (isRepair) return emojiMaps.SlotRepaired; + return emojiMaps.SlotFilled; + } + + private string GetSlotFilledTitle(bool isRepair) + { + if (isRepair) return $"Slot Repaired"; + return $"Slot Filled"; + } + private void AddMissedProofDetails(List lines, PeriodReport[] reports) { var reportsWithMissedProofs = reports.Where(r => r.MissedProofs.Length > 0).ToArray(); @@ -168,10 +182,10 @@ namespace TestNetRewarder lines.Add($"[{missedProof.FormatHost()}] missed proof for {FormatRequestId(missedProof.Request)} (slotIndex: {missedProof.SlotIndex})"); } - private void AddRequestBlock(RequestEvent requestEvent, string eventName, params string[] content) + private void AddRequestBlock(RequestEvent requestEvent, string icon, string eventName, params string[] content) { var blockNumber = $"[{requestEvent.Block.BlockNumber} {FormatDateTime(requestEvent.Block.Utc)}]"; - var title = $"{blockNumber} **{eventName}** {FormatRequestId(requestEvent)}"; + var title = $"{blockNumber} {icon} **{eventName}** {FormatRequestId(requestEvent)}"; AddBlock(requestEvent.Block.BlockNumber, title, content); } diff --git a/Tools/TestNetRewarder/Processor.cs b/Tools/TestNetRewarder/Processor.cs index 649ebf47..036f8795 100644 --- a/Tools/TestNetRewarder/Processor.cs +++ b/Tools/TestNetRewarder/Processor.cs @@ -25,7 +25,7 @@ namespace TestNetRewarder if (config.ProofReportHours < 1) throw new Exception("ProofReportHours must be one or greater"); builder = new RequestBuilder(); - eventsFormatter = new EventsFormatter(config); + eventsFormatter = new EventsFormatter(config, contracts.Deployment.Config); chainState = new ChainState(log, contracts, eventsFormatter, config.HistoryStartUtc, doProofPeriodMonitoring: config.ShowProofPeriodReports > 0); diff --git a/Tools/TraceContract/ChainRequestTracker.cs b/Tools/TraceContract/ChainRequestTracker.cs index 2e313ae8..9992f367 100644 --- a/Tools/TraceContract/ChainRequestTracker.cs +++ b/Tools/TraceContract/ChainRequestTracker.cs @@ -70,11 +70,11 @@ namespace TraceContract } } - public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { if (IsMyRequest(requestEvent)) { - output.LogSlotFilled(requestEvent, host, slotIndex); + output.LogSlotFilled(requestEvent, host, slotIndex, isRepair); } } diff --git a/Tools/TraceContract/Config.cs b/Tools/TraceContract/Config.cs index 3b49a77a..efb82645 100644 --- a/Tools/TraceContract/Config.cs +++ b/Tools/TraceContract/Config.cs @@ -4,7 +4,7 @@ { public string RpcEndpoint { get; } = "https://rpc.testnet.codex.storage"; public int GethPort { get; } = 443; - public string MarketplaceAddress { get; } = "0x7c7a749DE7156305E55775e7Ab3931abd6f7300E"; + public string MarketplaceAddress { get; } = "0x5378a4EA5dA2a548ce22630A3AE74b052000C62D"; public string TokenAddress { get; } = "0x34a22f3911De437307c6f4485931779670f78764"; public string Abi { get; } = @"[{""inputs"":[{""components"":[{""components"":[{""internalType"":""uint8"",""name"":""repairRewardPercentage"",""type"":""uint8""},{""internalType"":""uint8"",""name"":""maxNumberOfSlashes"",""type"":""uint8""},{""internalType"":""uint16"",""name"":""slashCriterion"",""type"":""uint16""},{""internalType"":""uint8"",""name"":""slashPercentage"",""type"":""uint8""}],""internalType"":""struct CollateralConfig"",""name"":""collateral"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""period"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""timeout"",""type"":""uint256""},{""internalType"":""uint8"",""name"":""downtime"",""type"":""uint8""},{""internalType"":""string"",""name"":""zkeyHash"",""type"":""string""}],""internalType"":""struct ProofConfig"",""name"":""proofs"",""type"":""tuple""}],""internalType"":""struct MarketplaceConfig"",""name"":""configuration"",""type"":""tuple""},{""internalType"":""contract IERC20"",""name"":""token_"",""type"":""address""},{""internalType"":""contract IGroth16Verifier"",""name"":""verifier"",""type"":""address""}],""stateMutability"":""nonpayable"",""type"":""constructor""},{""anonymous"":false,""inputs"":[{""indexed"":false,""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""}],""name"":""ProofSubmitted"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":true,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""RequestCancelled"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":true,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""RequestFailed"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":true,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""RequestFulfilled"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":true,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""},{""indexed"":false,""internalType"":""uint256"",""name"":""slotIndex"",""type"":""uint256""}],""name"":""SlotFilled"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":true,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""},{""indexed"":false,""internalType"":""uint256"",""name"":""slotIndex"",""type"":""uint256""}],""name"":""SlotFreed"",""type"":""event""},{""anonymous"":false,""inputs"":[{""indexed"":false,""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""},{""components"":[{""internalType"":""uint64"",""name"":""slots"",""type"":""uint64""},{""internalType"":""uint256"",""name"":""slotSize"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""duration"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""proofProbability"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""reward"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""collateral"",""type"":""uint256""},{""internalType"":""uint64"",""name"":""maxSlotLoss"",""type"":""uint64""}],""indexed"":false,""internalType"":""struct Ask"",""name"":""ask"",""type"":""tuple""},{""indexed"":false,""internalType"":""uint256"",""name"":""expiry"",""type"":""uint256""}],""name"":""StorageRequested"",""type"":""event""},{""inputs"":[],""name"":""config"",""outputs"":[{""components"":[{""components"":[{""internalType"":""uint8"",""name"":""repairRewardPercentage"",""type"":""uint8""},{""internalType"":""uint8"",""name"":""maxNumberOfSlashes"",""type"":""uint8""},{""internalType"":""uint16"",""name"":""slashCriterion"",""type"":""uint16""},{""internalType"":""uint8"",""name"":""slashPercentage"",""type"":""uint8""}],""internalType"":""struct CollateralConfig"",""name"":""collateral"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""period"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""timeout"",""type"":""uint256""},{""internalType"":""uint8"",""name"":""downtime"",""type"":""uint8""},{""internalType"":""string"",""name"":""zkeyHash"",""type"":""string""}],""internalType"":""struct ProofConfig"",""name"":""proofs"",""type"":""tuple""}],""internalType"":""struct MarketplaceConfig"",""name"":"""",""type"":""tuple""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""},{""internalType"":""uint256"",""name"":""slotIndex"",""type"":""uint256""},{""components"":[{""components"":[{""internalType"":""uint256"",""name"":""x"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""y"",""type"":""uint256""}],""internalType"":""struct G1Point"",""name"":""a"",""type"":""tuple""},{""components"":[{""components"":[{""internalType"":""uint256"",""name"":""real"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""imag"",""type"":""uint256""}],""internalType"":""struct Fp2Element"",""name"":""x"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""real"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""imag"",""type"":""uint256""}],""internalType"":""struct Fp2Element"",""name"":""y"",""type"":""tuple""}],""internalType"":""struct G2Point"",""name"":""b"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""x"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""y"",""type"":""uint256""}],""internalType"":""struct G1Point"",""name"":""c"",""type"":""tuple""}],""internalType"":""struct Groth16Proof"",""name"":""proof"",""type"":""tuple""}],""name"":""fillSlot"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""}],""name"":""freeSlot"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""}],""name"":""getActiveSlot"",""outputs"":[{""components"":[{""components"":[{""internalType"":""address"",""name"":""client"",""type"":""address""},{""components"":[{""internalType"":""uint64"",""name"":""slots"",""type"":""uint64""},{""internalType"":""uint256"",""name"":""slotSize"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""duration"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""proofProbability"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""reward"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""collateral"",""type"":""uint256""},{""internalType"":""uint64"",""name"":""maxSlotLoss"",""type"":""uint64""}],""internalType"":""struct Ask"",""name"":""ask"",""type"":""tuple""},{""components"":[{""internalType"":""string"",""name"":""cid"",""type"":""string""},{""internalType"":""bytes32"",""name"":""merkleRoot"",""type"":""bytes32""}],""internalType"":""struct Content"",""name"":""content"",""type"":""tuple""},{""internalType"":""uint256"",""name"":""expiry"",""type"":""uint256""},{""internalType"":""bytes32"",""name"":""nonce"",""type"":""bytes32""}],""internalType"":""struct Request"",""name"":""request"",""type"":""tuple""},{""internalType"":""uint256"",""name"":""slotIndex"",""type"":""uint256""}],""internalType"":""struct Marketplace.ActiveSlot"",""name"":"""",""type"":""tuple""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""}],""name"":""getChallenge"",""outputs"":[{""internalType"":""bytes32"",""name"":"""",""type"":""bytes32""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""}],""name"":""getHost"",""outputs"":[{""internalType"":""address"",""name"":"""",""type"":""address""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""}],""name"":""getPointer"",""outputs"":[{""internalType"":""uint8"",""name"":"""",""type"":""uint8""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""getRequest"",""outputs"":[{""components"":[{""internalType"":""address"",""name"":""client"",""type"":""address""},{""components"":[{""internalType"":""uint64"",""name"":""slots"",""type"":""uint64""},{""internalType"":""uint256"",""name"":""slotSize"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""duration"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""proofProbability"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""reward"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""collateral"",""type"":""uint256""},{""internalType"":""uint64"",""name"":""maxSlotLoss"",""type"":""uint64""}],""internalType"":""struct Ask"",""name"":""ask"",""type"":""tuple""},{""components"":[{""internalType"":""string"",""name"":""cid"",""type"":""string""},{""internalType"":""bytes32"",""name"":""merkleRoot"",""type"":""bytes32""}],""internalType"":""struct Content"",""name"":""content"",""type"":""tuple""},{""internalType"":""uint256"",""name"":""expiry"",""type"":""uint256""},{""internalType"":""bytes32"",""name"":""nonce"",""type"":""bytes32""}],""internalType"":""struct Request"",""name"":"""",""type"":""tuple""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""}],""name"":""isProofRequired"",""outputs"":[{""internalType"":""bool"",""name"":"""",""type"":""bool""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""},{""internalType"":""Periods.Period"",""name"":""period"",""type"":""uint256""}],""name"":""markProofAsMissing"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""}],""name"":""missingProofs"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""myRequests"",""outputs"":[{""internalType"":""RequestId[]"",""name"":"""",""type"":""bytes32[]""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""mySlots"",""outputs"":[{""internalType"":""SlotId[]"",""name"":"""",""type"":""bytes32[]""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""requestEnd"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""requestExpiry"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""requestState"",""outputs"":[{""internalType"":""enum RequestState"",""name"":"""",""type"":""uint8""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""components"":[{""internalType"":""address"",""name"":""client"",""type"":""address""},{""components"":[{""internalType"":""uint64"",""name"":""slots"",""type"":""uint64""},{""internalType"":""uint256"",""name"":""slotSize"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""duration"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""proofProbability"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""reward"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""collateral"",""type"":""uint256""},{""internalType"":""uint64"",""name"":""maxSlotLoss"",""type"":""uint64""}],""internalType"":""struct Ask"",""name"":""ask"",""type"":""tuple""},{""components"":[{""internalType"":""string"",""name"":""cid"",""type"":""string""},{""internalType"":""bytes32"",""name"":""merkleRoot"",""type"":""bytes32""}],""internalType"":""struct Content"",""name"":""content"",""type"":""tuple""},{""internalType"":""uint256"",""name"":""expiry"",""type"":""uint256""},{""internalType"":""bytes32"",""name"":""nonce"",""type"":""bytes32""}],""internalType"":""struct Request"",""name"":""request"",""type"":""tuple""}],""name"":""requestStorage"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""slotId"",""type"":""bytes32""}],""name"":""slotState"",""outputs"":[{""internalType"":""enum SlotState"",""name"":"""",""type"":""uint8""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""},{""components"":[{""components"":[{""internalType"":""uint256"",""name"":""x"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""y"",""type"":""uint256""}],""internalType"":""struct G1Point"",""name"":""a"",""type"":""tuple""},{""components"":[{""components"":[{""internalType"":""uint256"",""name"":""real"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""imag"",""type"":""uint256""}],""internalType"":""struct Fp2Element"",""name"":""x"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""real"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""imag"",""type"":""uint256""}],""internalType"":""struct Fp2Element"",""name"":""y"",""type"":""tuple""}],""internalType"":""struct G2Point"",""name"":""b"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""x"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""y"",""type"":""uint256""}],""internalType"":""struct G1Point"",""name"":""c"",""type"":""tuple""}],""internalType"":""struct Groth16Proof"",""name"":""proof"",""type"":""tuple""}],""name"":""submitProof"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[],""name"":""token"",""outputs"":[{""internalType"":""contract IERC20"",""name"":"""",""type"":""address""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""SlotId"",""name"":""id"",""type"":""bytes32""}],""name"":""willProofBeRequired"",""outputs"":[{""internalType"":""bool"",""name"":"""",""type"":""bool""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[{""internalType"":""RequestId"",""name"":""requestId"",""type"":""bytes32""}],""name"":""withdrawFunds"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""}]"; diff --git a/Tools/TraceContract/ElasticSearchLogDownloader.cs b/Tools/TraceContract/ElasticSearchLogDownloader.cs index a55d85ca..20e264f1 100644 --- a/Tools/TraceContract/ElasticSearchLogDownloader.cs +++ b/Tools/TraceContract/ElasticSearchLogDownloader.cs @@ -40,7 +40,7 @@ namespace TraceContract var queryTemplate = CreateQueryTemplate(podName, startUtc, endUtc); targetFile.Write($"Downloading '{podName}' to '{targetFile.Filename}'."); - var reconstructor = new LogReconstructor(targetFile, endpoint, queryTemplate); + var reconstructor = new LogReconstructor(log, targetFile, endpoint, queryTemplate); reconstructor.DownloadFullLog(); log.Log("Log download finished."); @@ -91,6 +91,7 @@ namespace TraceContract public class LogReconstructor { private readonly List queue = new List(); + private readonly ILog log; private readonly LogFile targetFile; private readonly IEndpoint endpoint; private readonly string queryTemplate; @@ -98,9 +99,11 @@ namespace TraceContract private string searchAfter = ""; private int lastHits = 1; private ulong? lastLogLine; + private uint linesWritten = 0; - public LogReconstructor(LogFile targetFile, IEndpoint endpoint, string queryTemplate) + public LogReconstructor(ILog log, LogFile targetFile, IEndpoint endpoint, string queryTemplate) { + this.log = log; this.targetFile = targetFile; this.endpoint = endpoint; this.queryTemplate = queryTemplate; @@ -113,6 +116,8 @@ namespace TraceContract QueryElasticSearch(); ProcessQueue(); } + + log.Log($"{linesWritten} lines written."); } private void QueryElasticSearch() @@ -124,6 +129,8 @@ namespace TraceContract var response = endpoint.HttpPostString("/_search", query); lastHits = response.hits.hits.Length; + log.Log($"pageSize: {sizeOfPage} after: {searchAfter} -> {lastHits} hits"); + if (lastHits > 0) { UpdateSearchAfter(response); @@ -176,7 +183,7 @@ namespace TraceContract private void ProcessQueue() { - if (lastLogLine == null) + if (lastLogLine == null && queue.Any()) { lastLogLine = queue.Min(q => q.Number) - 1; } @@ -208,6 +215,7 @@ namespace TraceContract private void WriteEntryToFile(LogQueueEntry currentEntry) { targetFile.Write(currentEntry.Message); + linesWritten++; } private void DeleteOldEntries(ulong wantedNumber) diff --git a/Tools/TraceContract/Output.cs b/Tools/TraceContract/Output.cs index 6365037b..16de2dc7 100644 --- a/Tools/TraceContract/Output.cs +++ b/Tools/TraceContract/Output.cs @@ -1,4 +1,5 @@ using System.Numerics; +using BlockchainUtils; using CodexContractsPlugin.ChainMonitor; using CodexContractsPlugin.Marketplace; using Logging; @@ -10,13 +11,13 @@ namespace TraceContract { private class Entry { - public Entry(DateTime utc, string msg) + public Entry(BlockTimeEntry blk, string msg) { - Utc = utc; + Blk = blk; Msg = msg; } - public DateTime Utc { get; } + public BlockTimeEntry Blk { get; } public string Msg { get; } } @@ -48,47 +49,47 @@ namespace TraceContract public void LogRequestCreated(RequestEvent requestEvent) { - Add(requestEvent.Block.Utc, $"Storage request created: '{requestEvent.Request.Request.Id}'"); + Add(requestEvent.Block, $"Storage request created: '{requestEvent.Request.Request.Id}'"); } public void LogRequestCancelled(RequestEvent requestEvent) { - Add(requestEvent.Block.Utc, "Expired"); + Add(requestEvent.Block, "Expired"); } public void LogRequestFailed(RequestEvent requestEvent) { - Add(requestEvent.Block.Utc, "Failed"); + Add(requestEvent.Block, "Failed"); } public void LogRequestFinished(RequestEvent requestEvent) { - Add(requestEvent.Block.Utc, "Finished"); + Add(requestEvent.Block, "Finished"); } public void LogRequestStarted(RequestEvent requestEvent) { - Add(requestEvent.Block.Utc, "Started"); + Add(requestEvent.Block, "Started"); } - public void LogSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex) + public void LogSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair) { - Add(requestEvent.Block.Utc, $"Slot filled. Index: {slotIndex} Host: '{host}'"); + Add(requestEvent.Block, $"Slot filled. Index: {slotIndex} Host: '{host}' isRepair: {isRepair}"); } public void LogSlotFreed(RequestEvent requestEvent, BigInteger slotIndex) { - Add(requestEvent.Block.Utc, $"Slot freed. Index: {slotIndex}"); + Add(requestEvent.Block, $"Slot freed. Index: {slotIndex}"); } public void LogSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex) { - Add(requestEvent.Block.Utc, $"Slot reservations full. Index: {slotIndex}"); + Add(requestEvent.Block, $"Slot reservations full. Index: {slotIndex}"); } public void WriteContractEvents() { - var sorted = entries.OrderBy(e => e.Utc).ToArray(); + var sorted = entries.OrderBy(e => e.Blk.Utc).ToArray(); foreach (var e in sorted) Write(e); } @@ -106,17 +107,17 @@ namespace TraceContract private void Write(Entry e) { - log.Log($"[{Time.FormatTimestamp(e.Utc)}] {e.Msg}"); + log.Log($"Block: {e.Blk.BlockNumber} [{Time.FormatTimestamp(e.Blk.Utc)}] {e.Msg}"); } public void LogReserveSlotCall(ReserveSlotFunction call) { - Add(call.Block.Utc, $"Reserve-slot called. Index: {call.SlotIndex} Host: '{call.FromAddress}'"); + Add(call.Block, $"Reserve-slot called. Block: {call.Block.BlockNumber} Index: {call.SlotIndex} Host: '{call.FromAddress}'"); } - private void Add(DateTime utc, string msg) + private void Add(BlockTimeEntry blk, string msg) { - entries.Add(new Entry(utc, msg)); + entries.Add(new Entry(blk, msg)); } } }