tx · n6cwhqFoj5W2LDqTeQBXhskSaZsYjiPmX6BiU1YrYc3 3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch: -0.02600000 Waves 2024.05.07 11:04 [3095488] smart account 3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch > SELF 0.00000000 Waves
{ "type": 13, "id": "n6cwhqFoj5W2LDqTeQBXhskSaZsYjiPmX6BiU1YrYc3", "fee": 2600000, "feeAssetId": null, "timestamp": 1715072454000, "version": 1, "sender": "3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch", "senderPublicKey": "3xjN6fjYDXBGUE1mcRw2Fvr4R6tEZnuJA98QFGF99sXd", "proofs": [ "56jFticvav8sAN3PmGiiVNLZSvV7P6btXvd1wh8eUF6P1GGgoGKQiXnu9qrhE1mLihNh3B8Q1VokdsDpY3SasibH" ], "script": "base64:CAIlCAISBAoCAgISBQoDAgIBEgUKAwICARIGCgQBAgIBEgMKAQISADYAB0lOVF9NQVgA//////////9/AAVXQVZFUwCAwtcvAAtNSU5fQkFMQU5DRQkAaAIAoJwBBQVXQVZFUwATTUFYX0JMT0NLU19BVF9FUE9DSAAyAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgAAxBRERSRVNTX1NJWkUAGgATTUFYX0JMT0NLU19TVFJfU0laRQkAZAIJAGgCAEAFE01BWF9CTE9DS1NfQVRfRVBPQ0gJAGUCBRNNQVhfQkxPQ0tTX0FUX0VQT0NIAAEAEHRoaXNFcG9jaERhdGFLZXkCDXRoaXNFcG9jaERhdGEADGFsbE1pbmVyc0tleQIJYWxsTWluZXJzAA5tYWluQ2hhaW5JZEtleQILbWFpbkNoYWluSWQADmxhc3RDaGFpbklkS2V5AgtsYXN0Q2hhaW5JZAAYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AhVsYXN0RXBvY2hCbG9ja3NOdW1iZXIADm1pbmVyUmV3YXJkS2V5AgttaW5lclJld2FyZAAKYmxvY2tNZXRhSwIIYmxvY2tfMHgBA3BhZAEBaQQBcwkApAMBBQFpBAckbWF0Y2gwCQCxAgEFAXMDCQAAAgABBQckbWF0Y2gwCQCsAgICBzAwMDAwMDAFAXMDCQAAAgACBQckbWF0Y2gwCQCsAgICBjAwMDAwMAUBcwMJAAACAAMFByRtYXRjaDAJAKwCAgIFMDAwMDAFAXMDCQAAAgAEBQckbWF0Y2gwCQCsAgICBDAwMDAFAXMDCQAAAgAFBQckbWF0Y2gwCQCsAgICAzAwMAUBcwMJAAACAAYFByRtYXRjaDAJAKwCAgICMDAFAXMDCQAAAgAHBQckbWF0Y2gwCQCsAgICATAFAXMFAXMBDGVwb2NoTWV0YUtleQEFZXBvY2gJAKwCAgIGZXBvY2hfCQEDcGFkAQUFZXBvY2gBDGNoYWluTWV0YUtleQEHY2hhaW5JZAkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkABZzdGFraW5nQ29udHJhY3RBZGRyZXNzCQEHQWRkcmVzcwEJARFAZXh0ck5hdGl2ZSgxMDUyKQIFBHRoaXMCFnN0YWtpbmdDb250cmFjdEFkZHJlc3MBEWdlbmVyYXRpbmdCYWxhbmNlAQdhZGRyZXNzBAckbWF0Y2gwCQCdCAIFFnN0YWtpbmdDb250cmFjdEFkZHJlc3MJAKwCAgIEJXNfXwkApQgBBQdhZGRyZXNzAwkAAQIFByRtYXRjaDACBlN0cmluZwQDc3RyBQckbWF0Y2gwBAlwYXJhbUxpc3QJALUJAgUDc3RyAgJfXwQKcHJldkhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAABBAtwcmV2QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAACBApuZXh0SGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJcGFyYW1MaXN0AAMEC25leHRCYWxhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJcGFyYW1MaXN0AAQDCQBnAgUGaGVpZ2h0BQpuZXh0SGVpZ2h0BQtuZXh0QmFsYW5jZQMJAGcCBQZoZWlnaHQFCnByZXZIZWlnaHQFC3ByZXZCYWxhbmNlAAAAAAEMYmxvY2tNZXRhS2V5AQdibG9ja0lkCQCsAgICCWJsb2NrTWV0YQkA3AQBBQdibG9ja0lkAQpjaGFpbklkS2V5AQlnZW5lcmF0b3IJAKwCAgIJY2hhaW5JZE9mCQDcBAEFCWdlbmVyYXRvcgEOY2hhaW5IZWlnaHRLZXkBB2NoYWluSWQJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgZIZWlnaHQBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKRmlyc3RCbG9jawETY2hhaW5MYXN0QmxvY2tJZEtleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCCUxhc3RCbG9jawETY2hhaW5BbGxCbG9ja0lkc0tleQIHY2hhaW5JZAFuCQCsAgIJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAglBbGxCbG9ja3MJAKQDAQUBbgEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIOQWxsQmxvY2tzTGFzdE4BDXN1cHBvcnRlcnNLZXkBB2NoYWluSWQJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgpTdXBwb3J0ZXJzARJtaW5lclJld2FyZEFkZHJlc3MBCW1pbmVyQWRkcgkArAICCQCsAgICBW1pbmVyBQltaW5lckFkZHICDVJld2FyZEFkZHJlc3MBEm1pbmVySm9pbkhlaWdodEtleQEJbWluZXJBZGRyCQCsAgIJAKwCAgIFbWluZXIFCW1pbmVyQWRkcgIKSm9pbkhlaWdodAEKbWluZXJQa0tleQENcmV3YXJkQWRkcmVzcwkArAICCQCsAgICBW1pbmVyBQ1yZXdhcmRBZGRyZXNzAgJQSwEQbGVhdmluZ01pbmVyc0tleQEFZXBvY2gJAKwCAgIPbGVhdmluZ01pbmVyc0F0CQCkAwEFBWVwb2NoAAttYWluQ2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5tYWluQ2hhaW5JZEtleQAAAA50aGlzRXBvY2hNaW5lcgQHJG1hdGNoMAkAoggBBRB0aGlzRXBvY2hEYXRhS2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQQcmF3VGhpc0Vwb2NoRGF0YQUHJG1hdGNoMAQNdGhpc0Vwb2NoRGF0YQkAtQkCBRByYXdUaGlzRXBvY2hEYXRhBQNTRVAECXRoaXNFcG9jaAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDXRoaXNFcG9jaERhdGEAAAMJAAACBQl0aGlzRXBvY2gFBmhlaWdodAkA2QQBCQCRAwIFDXRoaXNFcG9jaERhdGEAAQUEdW5pdAUEdW5pdAAJYWxsTWluZXJzBAckbWF0Y2gwCQCiCAEFDGFsbE1pbmVyc0tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3JhdwUHJG1hdGNoMAkAvAkCBQNyYXcFA1NFUAUDbmlsABBhbGxMZWF2aW5nTWluZXJzBAckbWF0Y2gwCQCiCAEJARBsZWF2aW5nTWluZXJzS2V5AQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBlN0cmluZwQDcmF3BQckbWF0Y2gwCQC8CQIFA3JhdwUDU0VQBQNuaWwBCWJsb2NrTWV0YQEHYmxvY2tJZAQEbWV0YQkBEUBleHRyTmF0aXZlKDEwNTcpAQkBDGJsb2NrTWV0YUtleQEFB2Jsb2NrSWQEEW1ldGFXaXRob3V0SGVpZ2h0CQDKAQIFBG1ldGEACAQWbWV0YVdpdGhvdXRIZWlnaHRFcG9jaAkAygECBRFtZXRhV2l0aG91dEhlaWdodAAIBAtibG9ja0hlaWdodAkAsQkBCQDJAQIFBG1ldGEACAQKYmxvY2tFcG9jaAkAsQkBCQDJAQIFEW1ldGFXaXRob3V0SGVpZ2h0AAgEC2Jsb2NrUGFyZW50CQDJAQIFFm1ldGFXaXRob3V0SGVpZ2h0RXBvY2gFD0JMT0NLX0hBU0hfU0laRQQOYmxvY2tHZW5lcmF0b3IJAMwBAgUEbWV0YQUMQUREUkVTU19TSVpFCQCWCgQFC2Jsb2NrSGVpZ2h0BQpibG9ja0Vwb2NoBQtibG9ja1BhcmVudAUOYmxvY2tHZW5lcmF0b3IBDHNldEVwb2NoRGF0YQEJZ2VuZXJhdG9yCQELU3RyaW5nRW50cnkCBRB0aGlzRXBvY2hEYXRhS2V5CQCsAgIJAKwCAgkApAMBBQZoZWlnaHQFA1NFUAkA2AQBCAUJZ2VuZXJhdG9yBWJ5dGVzAAskdDA0MTMxNTE4OAQJaGl0U291cmNlBAckbWF0Y2gwCAUJbGFzdEJsb2NrA3ZyZgMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAN2cmYFByRtYXRjaDAFA3ZyZggFCWxhc3RCbG9jaxNnZW5lcmF0aW9uU2lnbmF0dXJlCgEMcHJvY2Vzc01pbmVyAgRwcmV2BW1pbmVyBAskdDA0NDI5NDQ5MgUEcHJldgQJcHJldkRlbGF5CAULJHQwNDQyOTQ0OTICXzEECXByZXZNaW5lcggFCyR0MDQ0Mjk0NDkyAl8yBBBwcmV2VG90YWxCYWxhbmNlCAULJHQwNDQyOTQ0OTICXzMECnByZXZNaW5lcnMIBQskdDA0NDI5NDQ5MgJfNAQMbWluZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQVtaW5lcgQPd2F2ZXNHZW5CYWxhbmNlCAkA7wcBBQxtaW5lckFkZHJlc3MKZ2VuZXJhdGluZwQMbWluZXJCYWxhbmNlCQERZ2VuZXJhdGluZ0JhbGFuY2UBBQxtaW5lckFkZHJlc3MDAwMJAGYCBQtNSU5fQkFMQU5DRQUPd2F2ZXNHZW5CYWxhbmNlBgkAZwIAAAUMbWluZXJCYWxhbmNlBgkAZgIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEm1pbmVySm9pbkhlaWdodEtleQEFBW1pbmVyBQdJTlRfTUFYBQZoZWlnaHQFBHByZXYECW5leHREZWxheQkAhQcCBQxtaW5lckFkZHJlc3MFDG1pbmVyQmFsYW5jZQMJAGYCBQlwcmV2RGVsYXkFCW5leHREZWxheQkAlgoEBQluZXh0RGVsYXkFBW1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlCQDNCAIFCnByZXZNaW5lcnMFBW1pbmVyCQCWCgQFCXByZXZEZWxheQUJcHJldk1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlCQDNCAIFCnByZXZNaW5lcnMFBW1pbmVyCgACJGwJAM4IAgUJYWxsTWluZXJzBRBhbGxMZWF2aW5nTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEBQdJTlRfTUFYAgAAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQxwcm9jZXNzTWluZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgANY29tcHV0ZWREZWxheQgFCyR0MDQxMzE1MTg4Al8xABFjb21wdXRlZEdlbmVyYXRvcggFCyR0MDQxMzE1MTg4Al8yABRjb21wdXRlZFRvdGFsQmFsYW5jZQgFCyR0MDQxMzE1MTg4Al8zAA5maWx0ZXJlZE1pbmVycwgFCyR0MDQxMzE1MTg4Al80ABJzYWZlUm9sbGJhY2tIZWlnaHQKAQphZGRCYWxhbmNlAgNhY2MKYmxvY2tJZFN0cgQLJHQwNTMwMjUzNDYFA2FjYwQMdG90YWxCYWxhbmNlCAULJHQwNTMwMjUzNDYCXzEEBnByZXZJZAgFCyR0MDUzMDI1MzQ2Al8yBApnZW5lcmF0b3JzCAULJHQwNTMwMjUzNDYCXzMDCQBmAgUMdG90YWxCYWxhbmNlCQBpAgUUY29tcHV0ZWRUb3RhbEJhbGFuY2UAAgUDYWNjBAdibG9ja0lkCQDdBAEFCmJsb2NrSWRTdHIECWdlbmVyYXRvcgkBB0FkZHJlc3MBCAkBCWJsb2NrTWV0YQEFB2Jsb2NrSWQCXzQDCQEPY29udGFpbnNFbGVtZW50AgUKZ2VuZXJhdG9ycwUJZ2VuZXJhdG9yBQNhY2MEB2JhbGFuY2UJARFnZW5lcmF0aW5nQmFsYW5jZQEFCWdlbmVyYXRvcgkAlQoDCQBkAgUMdG90YWxCYWxhbmNlBQdiYWxhbmNlBQdibG9ja0lkCQDNCAIFCmdlbmVyYXRvcnMFCWdlbmVyYXRvcgoBC2dldEJsb2NrSWRzAQFuBAZyYXdTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQttYWluQ2hhaW5JZAUBbgIAAwkAAAIFBnJhd1N0cgIABQNuaWwJALwJAgUGcmF3U3RyBQNTRVAEBWxhc3ROCQELdmFsdWVPckVsc2UCCQCfCAEJARhjaGFpbkFsbEJsb2NrSWRzTGFzdE5LZXkBBQttYWluQ2hhaW5JZAAABAxhbGxCbG9ja3NJZHMJAM4IAgkAzggCCQDOCAIJAQtnZXRCbG9ja0lkcwEFBWxhc3ROCQELZ2V0QmxvY2tJZHMBCQBlAgUFbGFzdE4AAQkBC2dldEJsb2NrSWRzAQkAZQIFBWxhc3ROAAIJAQtnZXRCbG9ja0lkcwEJAGUCBQVsYXN0TgADBAskdDA2MTE0NjE4OAoAAiRsBQxhbGxCbG9ja3NJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMAAAEABQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCmFkZEJhbGFuY2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDIwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkAGUAZgBnAGgAaQBqAGsAbABtAG4AbwBwAHEAcgBzAHQAdQB2AHcAeAB5AHoAewB8AH0AfgB/AIABAIEBAIIBAIMBAIQBAIUBAIYBAIcBAIgBAIkBAIoBAIsBAIwBAI0BAI4BAI8BAJABAJEBAJIBAJMBAJQBAJUBAJYBAJcBAJgBAJkBAJoBAJsBAJwBAJ0BAJ4BAJ8BAKABAKEBAKIBAKMBAKQBAKUBAKYBAKcBAKgBAKkBAKoBAKsBAKwBAK0BAK4BAK8BALABALEBALIBALMBALQBALUBALYBALcBALgBALkBALoBALsBALwBAL0BAL4BAL8BAMABAMEBAMIBAMMBAMQBAMUBAMYBAMcBAMgBBAJfYggFCyR0MDYxMTQ2MTg4Al8xBAdibG9ja0lkCAULJHQwNjExNDYxODgCXzIICQEJYmxvY2tNZXRhAQUHYmxvY2tJZAJfMQERc3VwcG9ydGluZ0JhbGFuY2UBB2NoYWluSWQKAQphZGRCYWxhbmNlAgNhY2MMZ2VuZXJhdG9yU3RyBAskdDA2MzMzNjM2OQUDYWNjBAx0b3RhbEJhbGFuY2UIBQskdDA2MzMzNjM2OQJfMQQKZ2VuZXJhdG9ycwgFCyR0MDYzMzM2MzY5Al8yBAlnZW5lcmF0b3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDGdlbmVyYXRvclN0cgMJAQ9jb250YWluc0VsZW1lbnQCBQpnZW5lcmF0b3JzBQlnZW5lcmF0b3IFA2FjYwQHYmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUJZ2VuZXJhdG9yCQCUCgIJAGQCBQx0b3RhbEJhbGFuY2UFB2JhbGFuY2UJAM0IAgUKZ2VuZXJhdG9ycwUJZ2VuZXJhdG9yBA1hbGxHZW5lcmF0b3JzCQC8CQIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAUDU0VQBAskdDA2NjkxNjc1NgoAAiRsBQ1hbGxHZW5lcmF0b3JzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKYWRkQmFsYW5jZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIVTGlzdCBzaXplIGV4Y2VlZHMgMTAwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQEB2JhbGFuY2UIBQskdDA2NjkxNjc1NgJfMQQCX2cIBQskdDA2NjkxNjc1NgJfMgUHYmFsYW5jZQERZW5zdXJlTWluaW5nRXBvY2gBCWdlbmVyYXRvcgMJAQIhPQIJAKUIAQUJZ2VuZXJhdG9yBRFjb21wdXRlZEdlbmVyYXRvcgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkA2AQBCAUJZ2VuZXJhdG9yBWJ5dGVzAhsgaXMgbm90IGFsbG93ZWQgdG8gbWluZSBpbiAJAKQDAQUGaGVpZ2h0AhEgZXBvY2guIEV4cGVjdGVkIAURY29tcHV0ZWRHZW5lcmF0b3IFBHVuaXQBEmlzUmVmZXJlbmNlQ29ycmVjdAIJcmVmZXJlbmNlCWxhc3RCbG9jawQHJG1hdGNoMAUJbGFzdEJsb2NrAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCbGIFByRtYXRjaDADCQAAAgUJcmVmZXJlbmNlBQJsYgUEdW5pdAkAAgEJAKwCAgkArAICCQCsAgICLkV4cGVjdGVkIGEgcmVmZXJlbmNlIHRvIHRoZSBjaGFpbiBsYXN0IGJsb2NrOiAJANwEAQUCbGICBy4gR290OiAJANwEAQUJcmVmZXJlbmNlCQACAQILTWF0Y2ggZXJyb3IBD2NoYWluSXNJbmFjdGl2ZQEHY2hhaW5JZAQMZmlyc3RCbG9ja0lkCQERQGV4dHJOYXRpdmUoMTA1NykBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkCQBmAgUSc2FmZVJvbGxiYWNrSGVpZ2h0CAkBCWJsb2NrTWV0YQEFDGZpcnN0QmxvY2tJZAJfMQEZZW5zdXJlTWFpbk9ySW5hY3RpdmVDaGFpbgEJZ2VuZXJhdG9yBAckbWF0Y2gwCQCfCAEJAQpjaGFpbklkS2V5AQgFCWdlbmVyYXRvcgVieXRlcwMJAAECBQckbWF0Y2gwAgNJbnQECWN1cnJlbnRJZAUHJG1hdGNoMAMDCQAAAgUJY3VycmVudElkBQttYWluQ2hhaW5JZAYJAQ9jaGFpbklzSW5hY3RpdmUBBQljdXJyZW50SWQFBHVuaXQJAAIBCQCsAgICHG1pbmVyIGlzIG1pbmluZyBvdGhlciBjaGFpbiAJAKQDAQUJY3VycmVudElkBQR1bml0ARdlbnN1cmVBbHRDaGFpbkV4dGVuc2lvbgIJZ2VuZXJhdG9yB2NoYWluSWQEByRtYXRjaDAJAJ8IAQkBCmNoYWluSWRLZXkBCAUJZ2VuZXJhdG9yBWJ5dGVzAwkAAQIFByRtYXRjaDACA0ludAQJY3VycmVudElkBQckbWF0Y2gwAwkAAAIFCWN1cnJlbnRJZAUHY2hhaW5JZAUEdW5pdAQVZXh0ZW5kaW5nRmlyc3RCbG9ja0lkCQERQGV4dHJOYXRpdmUoMTA1NykBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkBBhtaW5lckN1cnJlbnRGaXJzdEJsb2NrSWQJARFAZXh0ck5hdGl2ZSgxMDU3KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFCWN1cnJlbnRJZAQZZXh0ZW5kaW5nRmlyc3RCbG9ja0hlaWdodAgJAQlibG9ja01ldGEBBRVleHRlbmRpbmdGaXJzdEJsb2NrSWQCXzEEHG1pbmVyQ3VycmVudEZpcnN0QmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQUYbWluZXJDdXJyZW50Rmlyc3RCbG9ja0lkAl8xAwkAZgIFGWV4dGVuZGluZ0ZpcnN0QmxvY2tIZWlnaHQFHG1pbmVyQ3VycmVudEZpcnN0QmxvY2tIZWlnaHQFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIcbWluZXIgaXMgbWluaW5nIG90aGVyIGNoYWluIAkApAMBBQljdXJyZW50SWQCJiwgaGVpZ2h0IG9mIHRoZSBhbHQgY2hhaW4gZmlyc3QgYmxvY2sgCQCkAwEFGWV4dGVuZGluZ0ZpcnN0QmxvY2tIZWlnaHQCPyBpcyBub3QgbGVzcyB0aGFuIGhlaWdodCBvZiB0aGUgbWluZXIgYWN0aXZlIGNoYWluIGZpcnN0IGJsb2NrIAkApAMBBRxtaW5lckN1cnJlbnRGaXJzdEJsb2NrSGVpZ2h0BQR1bml0ASBlbnN1cmVSZWZlcmVuY2VJc1NhZmVGb3JSb2xsYmFjawEJcmVmZXJlbmNlBAtzdGFydEhlaWdodAgJAQlibG9ja01ldGEBBQlyZWZlcmVuY2UCXzEDCQBmAgUSc2FmZVJvbGxiYWNrSGVpZ2h0BQtzdGFydEhlaWdodAkAAgEJAKwCAgkArAICCQCsAgICDXN0YXJ0IGhlaWdodCAJAKQDAQULc3RhcnRIZWlnaHQCHSBpcyBsZXNzIHRoYW4gbWluaW11bSBoZWlnaHQgCQCkAwEFEnNhZmVSb2xsYmFja0hlaWdodAUEdW5pdAESZW5zdXJlQ29ycmVjdEVwb2NoAQVlcG9jaAMJAAACBQVlcG9jaAUGaGVpZ2h0BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIaRXhwZWN0ZWQgYmxvY2sgZnJvbSBlcG9jaCAJAKQDAQUGaGVpZ2h0AgYuIEdvdCAJAKQDAQUFZXBvY2gBEWNoZWNrQmxvY2tzTnVtYmVyAAMJAGYCBRNNQVhfQkxPQ0tTX0FUX0VQT0NICQERQGV4dHJOYXRpdmUoMTA1NSkBBRhsYXN0RXBvY2hCbG9ja3NOdW1iZXJLZXkFBHVuaXQJAAIBAiJNYXggYmxvY2tzIG51bWJlciBhdCBlcG9jaCByZWFjaGVkAQxhZGRTdXBwb3J0ZXICB2NoYWluSWQJZ2VuZXJhdG9yBA1zdXBwb3J0ZXJzU3RyCQERQGV4dHJOYXRpdmUoMTA1OCkBCQENc3VwcG9ydGVyc0tleQEFB2NoYWluSWQECnN1cHBvcnRlcnMJALUJAgUNc3VwcG9ydGVyc1N0cgUDU0VQAwkBD2NvbnRhaW5zRWxlbWVudAIFCnN1cHBvcnRlcnMJAKUIAQUJZ2VuZXJhdG9yBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQdjaGFpbklkCQCsAgIJAKwCAgUNc3VwcG9ydGVyc1N0cgUDU0VQCQClCAEFCWdlbmVyYXRvcgUDbmlsBgFpAQthcHBlbmRCbG9jawIJYmxvY2tIYXNoCXJlZmVyZW5jZQQFY2hlY2sJARFjaGVja0Jsb2Nrc051bWJlcgADCQAAAgUFY2hlY2sFBWNoZWNrAwkBAiE9AgUOdGhpc0Vwb2NoTWluZXIICAUBaQxvcmlnaW5DYWxsZXIFYnl0ZXMEByRtYXRjaDAFDnRoaXNFcG9jaE1pbmVyAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IECmVwb2NoTWluZXIFByRtYXRjaDAJAAIBCQCsAgICOW5vdCBhbGxvd2VkIHRvIGZvcmdlIGJsb2NrcyBpbiB0aGlzIGVwb2NoLCBleHBlY3RlZCBmcm9tIAkA2AQBBQplcG9jaE1pbmVyCQACAQJAbm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGVwb2NoIG1pbmVyIGlzIGFic2VudAQHY2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEKY2hhaW5JZEtleQEICAUBaQxvcmlnaW5DYWxsZXIFYnl0ZXMFC21haW5DaGFpbklkBAtsYXN0QmxvY2tJZAkBEUBleHRyTmF0aXZlKDEwNTcpAQkBE2NoYWluTGFzdEJsb2NrSWRLZXkBBQdjaGFpbklkBAZjaGVjazIJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQlyZWZlcmVuY2UFC2xhc3RCbG9ja0lkAwkAAAIFBmNoZWNrMgUGY2hlY2syBAtjaGFpbkhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEOY2hhaW5IZWlnaHRLZXkBBQdjaGFpbklkAAAECW5ld0hlaWdodAkAZAIFC2NoYWluSGVpZ2h0AAEEDGJsb2Nrc051bWJlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBBRhsYXN0RXBvY2hCbG9ja3NOdW1iZXJLZXkAAAQMbmV3QmxvY2tNZXRhCQDLAQIJAMsBAgkAywECCQCaAwEFCW5ld0hlaWdodAkAmgMBBQZoZWlnaHQFC2xhc3RCbG9ja0lkCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQxibG9ja01ldGFLZXkBBQlibG9ja0hhc2gFDG5ld0Jsb2NrTWV0YQkAzAgCCQELQmluYXJ5RW50cnkCCQCsAgIFCmJsb2NrTWV0YUsJANwEAQUJYmxvY2tIYXNoBQxuZXdCbG9ja01ldGEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5jaGFpbkhlaWdodEtleQEFB2NoYWluSWQFCW5ld0hlaWdodAkAzAgCCQELQmluYXJ5RW50cnkCCQETY2hhaW5MYXN0QmxvY2tJZEtleQEFB2NoYWluSWQFCWJsb2NrSGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQEMY2hhaW5NZXRhS2V5AQUHY2hhaW5JZAkArAICCQCsAgIJAKQDAQUJbmV3SGVpZ2h0BQNTRVAJANwEAQUJYmxvY2tIYXNoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhsYXN0RXBvY2hCbG9ja3NOdW1iZXJLZXkJAGQCBQxibG9ja3NOdW1iZXIAAQkAzAgCCQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXICAywwLAkA3AQBBQlibG9ja0hhc2gFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ9leHRlbmRNYWluQ2hhaW4DCWJsb2NrSGFzaAlyZWZlcmVuY2UFZXBvY2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQKY2hlY2tDaGFpbgkBGWVuc3VyZU1haW5PckluYWN0aXZlQ2hhaW4BCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQLY2hhaW5IZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDmNoYWluSGVpZ2h0S2V5AQULbWFpbkNoYWluSWQAAAQQbGFzdFZhbGlkQmxvY2tJZAkAoQgBCQETY2hhaW5MYXN0QmxvY2tJZEtleQEFC21haW5DaGFpbklkBA5jaGVja1JlZmVyZW5jZQkBEmlzUmVmZXJlbmNlQ29ycmVjdAIFCXJlZmVyZW5jZQUQbGFzdFZhbGlkQmxvY2tJZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDWJsb2NrSWRzTGFzdE4JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBGGNoYWluQWxsQmxvY2tJZHNMYXN0TktleQEFC21haW5DaGFpbklkAAAECGJsb2NrSWRzCQELdmFsdWVPckVsc2UCCQCiCAEJARNjaGFpbkFsbEJsb2NrSWRzS2V5AgULbWFpbkNoYWluSWQFDWJsb2NrSWRzTGFzdE4CAAQJbmV3SGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQRdXBkYXRlQWxsQmxvY2tJZHMDCQBnAgkAsQIBBQhibG9ja0lkcwUTTUFYX0JMT0NLU19TVFJfU0laRQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBGGNoYWluQWxsQmxvY2tJZHNMYXN0TktleQEFC21haW5DaGFpbklkCQBkAgUNYmxvY2tJZHNMYXN0TgABCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNjaGFpbkFsbEJsb2NrSWRzS2V5AgULbWFpbkNoYWluSWQJAGQCBQ1ibG9ja0lkc0xhc3ROAAEJANwEAQUJYmxvY2tIYXNoBQNuaWwEC25ld0Jsb2NrSWRzAwkAAAIFCGJsb2NrSWRzAgAJANwEAQUJYmxvY2tIYXNoCQCsAgIJAKwCAgkA3AQBBQlibG9ja0hhc2gFA1NFUAUIYmxvY2tJZHMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQttYWluQ2hhaW5JZAUNYmxvY2tJZHNMYXN0TgULbmV3QmxvY2tJZHMFA25pbAQMZmlyc3RCbG9ja0lkBAckbWF0Y2gwBRBsYXN0VmFsaWRCbG9ja0lkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwBQNuaWwJAMwIAgkBC0JpbmFyeUVudHJ5AgkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQULbWFpbkNoYWluSWQFCWJsb2NrSGFzaAUDbmlsBAxuZXdCbG9ja01ldGEJAMsBAgkAywECCQDLAQIJAJoDAQUJbmV3SGVpZ2h0CQCaAwEFBmhlaWdodAUJcmVmZXJlbmNlCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDOCAIJAM4IAgkAzAgCCQELQmluYXJ5RW50cnkCCQEMYmxvY2tNZXRhS2V5AQUJYmxvY2tIYXNoBQxuZXdCbG9ja01ldGEJAMwIAgkBC0JpbmFyeUVudHJ5AgkArAICBQpibG9ja01ldGFLCQDcBAEFCWJsb2NrSGFzaAUMbmV3QmxvY2tNZXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOY2hhaW5IZWlnaHRLZXkBBQttYWluQ2hhaW5JZAUJbmV3SGVpZ2h0CQDMCAIJAQtCaW5hcnlFbnRyeQIJARNjaGFpbkxhc3RCbG9ja0lkS2V5AQULbWFpbkNoYWluSWQFCWJsb2NrSGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQEMY2hhaW5NZXRhS2V5AQULbWFpbkNoYWluSWQJAKwCAgkArAICCQCkAwEFCW5ld0hlaWdodAUDU0VQCQDcBAEFCWJsb2NrSGFzaAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCmNoYWluSWRLZXkBCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzBQttYWluQ2hhaW5JZAkAzAgCCQEMc2V0RXBvY2hEYXRhAQgFAWkMb3JpZ2luQ2FsbGVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhsYXN0RXBvY2hCbG9ja3NOdW1iZXJLZXkAAQkAzAgCCQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXICAywwLAkA3AQBBQlibG9ja0hhc2gFA25pbAUMZmlyc3RCbG9ja0lkBRF1cGRhdGVBbGxCbG9ja0lkcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1zdGFydEFsdENoYWluAwlibG9ja0hhc2gJcmVmZXJlbmNlBWVwb2NoBApjaGVja0Vwb2NoCQESZW5zdXJlQ29ycmVjdEVwb2NoAQUFZXBvY2gDCQAAAgUKY2hlY2tFcG9jaAUKY2hlY2tFcG9jaAQOY2hlY2tSZWZlcmVuY2UJASBlbnN1cmVSZWZlcmVuY2VJc1NhZmVGb3JSb2xsYmFjawEFCXJlZmVyZW5jZQMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBApjaGVja0NoYWluCQEZZW5zdXJlTWFpbk9ySW5hY3RpdmVDaGFpbgEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBApuZXdDaGFpbklkCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5sYXN0Q2hhaW5JZEtleQAAAAEECW5ld0hlaWdodAkAZAIICQEJYmxvY2tNZXRhAQUJcmVmZXJlbmNlAl8xAAEEDG5ld0Jsb2NrTWV0YQkAywECCQDLAQIJAMsBAgkAmgMBBQluZXdIZWlnaHQJAJoDAQUGaGVpZ2h0BQlyZWZlcmVuY2UICAUBaQxvcmlnaW5DYWxsZXIFYnl0ZXMJAMwIAgkBC0JpbmFyeUVudHJ5AgkBDGJsb2NrTWV0YUtleQEFCWJsb2NrSGFzaAUMbmV3QmxvY2tNZXRhCQDMCAIJAQtCaW5hcnlFbnRyeQIJAKwCAgUKYmxvY2tNZXRhSwkA3AQBBQlibG9ja0hhc2gFDG5ld0Jsb2NrTWV0YQkAzAgCCQELQmluYXJ5RW50cnkCCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQpuZXdDaGFpbklkBQlibG9ja0hhc2gJAMwIAgkBC0JpbmFyeUVudHJ5AgkBE2NoYWluTGFzdEJsb2NrSWRLZXkBBQpuZXdDaGFpbklkBQlibG9ja0hhc2gJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQpuZXdDaGFpbklkAAAJANwEAQUJYmxvY2tIYXNoCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOY2hhaW5IZWlnaHRLZXkBBQpuZXdDaGFpbklkBQluZXdIZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGNoYWluTWV0YUtleQEFCm5ld0NoYWluSWQJAKwCAgkArAICCQCkAwEFCW5ld0hlaWdodAUDU0VQCQDcBAEFCWJsb2NrSGFzaAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCmNoYWluSWRLZXkBCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzBQpuZXdDaGFpbklkCQDMCAIJAQxzZXRFcG9jaERhdGEBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQpuZXdDaGFpbklkCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AAEJAMwIAgkBDEludGVnZXJFbnRyeQIFDmxhc3RDaGFpbklkS2V5BQpuZXdDaGFpbklkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQClCAEIBQFpDG9yaWdpbkNhbGxlcgIDLDAsCQDcBAEFCWJsb2NrSGFzaAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmV4dGVuZEFsdENoYWluBAdjaGFpbklkCWJsb2NrSGFzaAlyZWZlcmVuY2UFZXBvY2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQKY2hlY2tDaGFpbgkBF2Vuc3VyZUFsdENoYWluRXh0ZW5zaW9uAggFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkAwkAAAIFCmNoZWNrQ2hhaW4FCmNoZWNrQ2hhaW4EDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUJcmVmZXJlbmNlCQChCAEJARNjaGFpbkxhc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEC2NoYWluSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJAQ5jaGFpbkhlaWdodEtleQEFB2NoYWluSWQAAAQNYmxvY2tJZHNMYXN0TgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQUHY2hhaW5JZAAABAhibG9ja0lkcwkBEUBleHRyTmF0aXZlKDEwNTgpAQkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQdjaGFpbklkBQ1ibG9ja0lkc0xhc3ROBAluZXdIZWlnaHQJAGQCBQtjaGFpbkhlaWdodAABBBF1cGRhdGVBbGxCbG9ja0lkcwMJAGcCCQCxAgEFCGJsb2NrSWRzBRNNQVhfQkxPQ0tTX1NUUl9TSVpFCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQUHY2hhaW5JZAkAZAIFDWJsb2NrSWRzTGFzdE4AAQkAzAgCCQELU3RyaW5nRW50cnkCCQETY2hhaW5BbGxCbG9ja0lkc0tleQIFB2NoYWluSWQJAGQCBQ1ibG9ja0lkc0xhc3ROAAEJANwEAQUJYmxvY2tIYXNoBQNuaWwEC25ld0Jsb2NrSWRzCQCsAgIJAKwCAgkA3AQBBQlibG9ja0hhc2gFA1NFUAUIYmxvY2tJZHMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQdjaGFpbklkBQ1ibG9ja0lkc0xhc3ROBQtuZXdCbG9ja0lkcwUDbmlsBA5tYWluQ2hhaW5FbnRyeQMJAGYCCQERc3VwcG9ydGluZ0JhbGFuY2UBBQdjaGFpbklkCQBpAgUUY29tcHV0ZWRUb3RhbEJhbGFuY2UAAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObWFpbkNoYWluSWRLZXkFB2NoYWluSWQFA25pbAUDbmlsBAxuZXdCbG9ja01ldGEJAMsBAgkAywECCQDLAQIJAJoDAQUJbmV3SGVpZ2h0CQCaAwEFBmhlaWdodAUJcmVmZXJlbmNlCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDOCAIJAM4IAgkAzggCCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQxibG9ja01ldGFLZXkBBQlibG9ja0hhc2gFDG5ld0Jsb2NrTWV0YQkAzAgCCQELQmluYXJ5RW50cnkCCQCsAgIFCmJsb2NrTWV0YUsJANwEAQUJYmxvY2tIYXNoBQxuZXdCbG9ja01ldGEJAMwIAgkBC0JpbmFyeUVudHJ5AgkBE2NoYWluTGFzdEJsb2NrSWRLZXkBBQdjaGFpbklkBQlibG9ja0hhc2gJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5jaGFpbkhlaWdodEtleQEFB2NoYWluSWQFCW5ld0hlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCCQEMY2hhaW5NZXRhS2V5AQUHY2hhaW5JZAkArAICCQCsAgIJAKQDAQUJbmV3SGVpZ2h0BQNTRVAJANwEAQUJYmxvY2tIYXNoCQDMCAIJAQxzZXRFcG9jaERhdGEBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQpjaGFpbklkS2V5AQgIBQFpDG9yaWdpbkNhbGxlcgVieXRlcwUHY2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AAEJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyAgMsMCwJANwEAQUJYmxvY2tIYXNoBQNuaWwFDm1haW5DaGFpbkVudHJ5CQEMYWRkU3VwcG9ydGVyAgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBRF1cGRhdGVBbGxCbG9ja0lkcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRqb2luAQ1yZXdhcmRBZGRyZXNzCgESY2hlY2tSZXdhcmRBZGRyZXNzAQdhZGRyZXNzBAckbWF0Y2gwCQChCAEJAQptaW5lclBrS2V5AQUHYWRkcmVzcwMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACBQJwawgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIRTDIgbWluZXIgYWRkcmVzcyAFB2FkZHJlc3MCGCBpcyBhbHJlYWR5IGxpbmtlZCB3aXRoIAkA2AQBBQJwawUEdW5pdAMJAGYCBQtNSU5fQkFMQU5DRQgJAO8HAQgFAWkMb3JpZ2luQ2FsbGVyCmdlbmVyYXRpbmcJAAIBCQCsAgIJAKwCAgkArAICAiFJbnN1ZmZpY2llbnQgZ2VuZXJhdGluZyBiYWxhbmNlOiAJAKQDAQgJAO8HAQgFAWkMb3JpZ2luQ2FsbGVyCmdlbmVyYXRpbmcCDC4gUmVxdWlyZWQ6IAkApAMBBQtNSU5fQkFMQU5DRQMJAQIhPQIJAMgBAQUNcmV3YXJkQWRkcmVzcwAUCQACAQIlcmV3YXJkQWRkcmVzcyBzaG91bGQgYmUgYW4gTDIgYWRkcmVzcwoBDmNoZWNrRXhpc3RlbmNlAgZleGlzdHMFbWluZXIDBQZleGlzdHMGCQAAAgUFbWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBA1hbHJlYWR5RXhpc3RzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAHCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ5jaGVja0V4aXN0ZW5jZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAwUNYWxyZWFkeUV4aXN0cwUDbmlsBAhuZXdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEEHJld2FyZEFkZHJlc3NIZXgJANwEAQUNcmV3YXJkQWRkcmVzcwQFY2hlY2sJARJjaGVja1Jld2FyZEFkZHJlc3MBBRByZXdhcmRBZGRyZXNzSGV4AwkAAAIFBWNoZWNrBQVjaGVjawoBDWZpbHRlckxlYXZpbmcCA2FjYwVtaW5lcgQNJHQwMTgyOTQxODMyNgUDYWNjBAlhY2NNaW5lcnMIBQ0kdDAxODI5NDE4MzI2Al8xBAlpc1VwZGF0ZWQIBQ0kdDAxODI5NDE4MzI2Al8yAwkAAAIFBW1pbmVyBQhuZXdNaW5lcgkAlAoCBQlhY2NNaW5lcnMGCQCUCgIJAM0IAgUJYWNjTWluZXJzBQVtaW5lcgUJaXNVcGRhdGVkBAluZXdNaW5lcnMDCQAAAgkAkAMBBQlhbGxNaW5lcnMAAAUIbmV3TWluZXIJAKwCAgkArAICCQC6CQIFCWFsbE1pbmVycwUDU0VQBQNTRVAFCG5ld01pbmVyBA0kdDAxODU5MDE4NjgwCgACJGwFEGFsbExlYXZpbmdNaW5lcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAcKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDWZpbHRlckxlYXZpbmcCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYxXzICCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECCQEFJGYxXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgQQbmV3TGVhdmluZ01pbmVycwgFDSR0MDE4NTkwMTg2ODACXzEECWlzVXBkYXRlZAgFDSR0MDE4NTkwMTg2ODACXzIEFm5ld0xlYXZpbmdNaW5lcnNBY3Rpb24DCQECIT0CBRBuZXdMZWF2aW5nTWluZXJzBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGxlYXZpbmdNaW5lcnNLZXkBBQZoZWlnaHQJALoJAgUQbmV3TGVhdmluZ01pbmVycwUDU0VQBQNuaWwDCQECIT0CBRBhbGxMZWF2aW5nTWluZXJzBQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGxlYXZpbmdNaW5lcnNLZXkBBQZoZWlnaHQFA25pbAUDbmlsBApqb2luSGVpZ2h0AwUJaXNVcGRhdGVkBQZoZWlnaHQJAGQCBQZoZWlnaHQAAQQYZGVsZXRlT2xkUmV3YXJkQWRkcmVzc1BrBAckbWF0Y2gwCQChCAEJARJtaW5lclJld2FyZEFkZHJlc3MBBQhuZXdNaW5lcgMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBApvbGRBZGRyZXNzBQckbWF0Y2gwAwkAAAIFCm9sZEFkZHJlc3MFDXJld2FyZEFkZHJlc3MFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBCQEKbWluZXJQa0tleQEJANwEAQUKb2xkQWRkcmVzcwUDbmlsBQNuaWwJAM4IAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQUJbmV3TWluZXJzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESbWluZXJKb2luSGVpZ2h0S2V5AQUIbmV3TWluZXIFCmpvaW5IZWlnaHQJAMwIAgkBC0JpbmFyeUVudHJ5AgkBEm1pbmVyUmV3YXJkQWRkcmVzcwEFCG5ld01pbmVyBQ1yZXdhcmRBZGRyZXNzCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQptaW5lclBrS2V5AQUQcmV3YXJkQWRkcmVzc0hleAgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQNuaWwFFm5ld0xlYXZpbmdNaW5lcnNBY3Rpb24FGGRlbGV0ZU9sZFJld2FyZEFkZHJlc3NQawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVsZWF2ZQAEDGxlYXZpbmdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIKAQtmaWx0ZXJNaW5lcgIDYWNjBW1pbmVyAwkAAAIFBW1pbmVyBQxsZWF2aW5nTWluZXIFA2FjYwkAzQgCBQNhY2MFBW1pbmVyBApyZXN0TWluZXJzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQELZmlsdGVyTWluZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgMJAAACBQ50aGlzRXBvY2hNaW5lcggIBQFpDG9yaWdpbkNhbGxlcgVieXRlcwkAAgECHGRlc2lnbmF0ZWQgbWluZXIgY2FuJ3QgbGVhdmUEByRtYXRjaDAJAJ8IAQkBEm1pbmVySm9pbkhlaWdodEtleQEFDGxlYXZpbmdNaW5lcgMJAAECBQckbWF0Y2gwAgNJbnQEC21pbmVySGVpZ2h0BQckbWF0Y2gwAwkAZgIFC21pbmVySGVpZ2h0BQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5CQC6CQIFCnJlc3RNaW5lcnMFA1NFUAkAzAgCCQELRGVsZXRlRW50cnkBCQESbWluZXJKb2luSGVpZ2h0S2V5AQUMbGVhdmluZ01pbmVyBQNuaWwEEG9sZExlYXZpbmdNaW5lcnMJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEGxlYXZpbmdNaW5lcnNLZXkBBQZoZWlnaHQCAAQQbmV3TGVhdmluZ01pbmVycwMJAAACBRBvbGRMZWF2aW5nTWluZXJzAgAFDGxlYXZpbmdNaW5lcgkArAICCQCsAgIFEG9sZExlYXZpbmdNaW5lcnMFA1NFUAUMbGVhdmluZ01pbmVyCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQkAugkCBQpyZXN0TWluZXJzBQNTRVAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEm1pbmVySm9pbkhlaWdodEtleQEFDGxlYXZpbmdNaW5lcgkAzAgCCQELU3RyaW5nRW50cnkCCQEQbGVhdmluZ01pbmVyc0tleQEFBmhlaWdodAUQbmV3TGVhdmluZ01pbmVycwUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQkAugkCBQpyZXN0TWluZXJzBQNTRVAFA25pbACg/dLn", "chainId": 84, "height": 3095488, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9LVcNq4yYu4tSAK7dib3z1Wimo7hRHSdnK5CvW66kuni Next: 2EWu1PugPUm3LTX33R1oGgkX4qEnsnaJu55LKi6LmoUn Diff:
Old | New | Differences | |
---|---|---|---|
55 | 55 | ||
56 | 56 | ||
57 | 57 | func epochMetaKey (epoch) = ("epoch_" + pad(epoch)) | |
58 | + | ||
59 | + | ||
60 | + | func chainMetaKey (chainId) = ("chain_" + pad(chainId)) | |
58 | 61 | ||
59 | 62 | ||
60 | 63 | let stakingContractAddress = Address(getBinaryValue(this, "stakingContractAddress")) | |
154 | 157 | func setEpochData (generator) = StringEntry(thisEpochDataKey, ((toString(height) + SEP) + toBase58String(generator.bytes))) | |
155 | 158 | ||
156 | 159 | ||
157 | - | let $ | |
160 | + | let $t041315188 = { | |
158 | 161 | let hitSource = match lastBlock.vrf { | |
159 | 162 | case vrf: ByteVector => | |
160 | 163 | vrf | |
162 | 165 | lastBlock.generationSignature | |
163 | 166 | } | |
164 | 167 | func processMiner (prev,miner) = { | |
165 | - | let $ | |
166 | - | let prevDelay = $ | |
167 | - | let prevMiner = $ | |
168 | - | let prevTotalBalance = $ | |
169 | - | let prevMiners = $ | |
168 | + | let $t044294492 = prev | |
169 | + | let prevDelay = $t044294492._1 | |
170 | + | let prevMiner = $t044294492._2 | |
171 | + | let prevTotalBalance = $t044294492._3 | |
172 | + | let prevMiners = $t044294492._4 | |
170 | 173 | let minerAddress = addressFromStringValue(miner) | |
171 | 174 | let wavesGenBalance = wavesBalance(minerAddress).generating | |
172 | 175 | let minerBalance = generatingBalance(minerAddress) | |
198 | 201 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
199 | 202 | } | |
200 | 203 | ||
201 | - | let computedDelay = $ | |
204 | + | let computedDelay = $t041315188._1 | |
202 | 205 | ||
203 | - | let computedGenerator = $ | |
206 | + | let computedGenerator = $t041315188._2 | |
204 | 207 | ||
205 | - | let computedTotalBalance = $ | |
208 | + | let computedTotalBalance = $t041315188._3 | |
206 | 209 | ||
207 | - | let filteredMiners = $ | |
210 | + | let filteredMiners = $t041315188._4 | |
208 | 211 | ||
209 | 212 | let safeRollbackHeight = { | |
210 | 213 | func addBalance (acc,blockIdStr) = { | |
211 | - | let $ | |
212 | - | let totalBalance = $ | |
213 | - | let prevId = $ | |
214 | - | let generators = $ | |
214 | + | let $t053025346 = acc | |
215 | + | let totalBalance = $t053025346._1 | |
216 | + | let prevId = $t053025346._2 | |
217 | + | let generators = $t053025346._3 | |
215 | 218 | if ((totalBalance > (computedTotalBalance / 2))) | |
216 | 219 | then acc | |
217 | 220 | else { | |
235 | 238 | ||
236 | 239 | let lastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(mainChainId)), 0) | |
237 | 240 | let allBlocksIds = (((getBlockIds(lastN) ++ getBlockIds((lastN - 1))) ++ getBlockIds((lastN - 2))) ++ getBlockIds((lastN - 3))) | |
238 | - | let $ | |
241 | + | let $t061146188 = { | |
239 | 242 | let $l = allBlocksIds | |
240 | 243 | let $s = size($l) | |
241 | 244 | let $acc0 = $Tuple3(0, base58'', nil) | |
249 | 252 | ||
250 | 253 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100), 101), 102), 103), 104), 105), 106), 107), 108), 109), 110), 111), 112), 113), 114), 115), 116), 117), 118), 119), 120), 121), 122), 123), 124), 125), 126), 127), 128), 129), 130), 131), 132), 133), 134), 135), 136), 137), 138), 139), 140), 141), 142), 143), 144), 145), 146), 147), 148), 149), 150), 151), 152), 153), 154), 155), 156), 157), 158), 159), 160), 161), 162), 163), 164), 165), 166), 167), 168), 169), 170), 171), 172), 173), 174), 175), 176), 177), 178), 179), 180), 181), 182), 183), 184), 185), 186), 187), 188), 189), 190), 191), 192), 193), 194), 195), 196), 197), 198), 199), 200) | |
251 | 254 | } | |
252 | - | let _b = $ | |
253 | - | let blockId = $ | |
255 | + | let _b = $t061146188._1 | |
256 | + | let blockId = $t061146188._2 | |
254 | 257 | blockMeta(blockId)._1 | |
255 | 258 | } | |
256 | 259 | ||
257 | 260 | func supportingBalance (chainId) = { | |
258 | 261 | func addBalance (acc,generatorStr) = { | |
259 | - | let $ | |
260 | - | let totalBalance = $ | |
261 | - | let generators = $ | |
262 | + | let $t063336369 = acc | |
263 | + | let totalBalance = $t063336369._1 | |
264 | + | let generators = $t063336369._2 | |
262 | 265 | let generator = addressFromStringValue(generatorStr) | |
263 | 266 | if (containsElement(generators, generator)) | |
264 | 267 | then acc | |
269 | 272 | } | |
270 | 273 | ||
271 | 274 | let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP) | |
272 | - | let $ | |
275 | + | let $t066916756 = { | |
273 | 276 | let $l = allGenerators | |
274 | 277 | let $s = size($l) | |
275 | 278 | let $acc0 = $Tuple2(0, nil) | |
283 | 286 | ||
284 | 287 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100) | |
285 | 288 | } | |
286 | - | let balance = $ | |
287 | - | let _g = $ | |
289 | + | let balance = $t066916756._1 | |
290 | + | let _g = $t066916756._2 | |
288 | 291 | balance | |
289 | 292 | } | |
290 | 293 | ||
390 | 393 | let newHeight = (chainHeight + 1) | |
391 | 394 | let blocksNumber = valueOrElse(getInteger(lastEpochBlocksNumberKey), 0) | |
392 | 395 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + lastBlockId) + i.originCaller.bytes) | |
393 | - | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(chainId), newHeight), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(lastEpochBlocksNumberKey, (blocksNumber + 1)), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
396 | + | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(chainId), newHeight), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), StringEntry(chainMetaKey(chainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(lastEpochBlocksNumberKey, (blocksNumber + 1)), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
394 | 397 | } | |
395 | 398 | else throw("Strict value is not equal to itself.") | |
396 | 399 | } | |
433 | 436 | [BinaryEntry(chainFirstBlockIdKey(mainChainId), blockHash)] | |
434 | 437 | } | |
435 | 438 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
436 | - | (([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(mainChainId), newHeight), BinaryEntry(chainLastBlockIdKey(mainChainId), blockHash), IntegerEntry(chainIdKey(i.originCaller.bytes), mainChainId), setEpochData(i.originCaller), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ firstBlockId) ++ updateAllBlockIds) | |
439 | + | (([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(mainChainId), newHeight), BinaryEntry(chainLastBlockIdKey(mainChainId), blockHash), StringEntry(chainMetaKey(mainChainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(chainIdKey(i.originCaller.bytes), mainChainId), setEpochData(i.originCaller), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ firstBlockId) ++ updateAllBlockIds) | |
437 | 440 | } | |
438 | 441 | else throw("Strict value is not equal to itself.") | |
439 | 442 | } | |
463 | 466 | let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1) | |
464 | 467 | let newHeight = (blockMeta(reference)._1 + 1) | |
465 | 468 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
466 | - | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainFirstBlockIdKey(newChainId), blockHash), BinaryEntry(chainLastBlockIdKey(newChainId), blockHash), StringEntry(chainAllBlockIdsKey(newChainId, 0), toBase16String(blockHash)), IntegerEntry(chainHeightKey(newChainId), newHeight), IntegerEntry(chainIdKey(i.originCaller.bytes), newChainId), setEpochData(i.originCaller), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastEpochBlocksNumberKey, 1), IntegerEntry(lastChainIdKey, newChainId), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
469 | + | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainFirstBlockIdKey(newChainId), blockHash), BinaryEntry(chainLastBlockIdKey(newChainId), blockHash), StringEntry(chainAllBlockIdsKey(newChainId, 0), toBase16String(blockHash)), IntegerEntry(chainHeightKey(newChainId), newHeight), StringEntry(chainMetaKey(newChainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(chainIdKey(i.originCaller.bytes), newChainId), setEpochData(i.originCaller), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastEpochBlocksNumberKey, 1), IntegerEntry(lastChainIdKey, newChainId), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
467 | 470 | } | |
468 | 471 | else throw("Strict value is not equal to itself.") | |
469 | 472 | } | |
504 | 507 | then [IntegerEntry(mainChainIdKey, chainId)] | |
505 | 508 | else nil | |
506 | 509 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
507 | - | ((([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(chainHeightKey(chainId), newHeight), setEpochData(i.originCaller), IntegerEntry(chainIdKey(i.originCaller.bytes), chainId), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ mainChainEntry) ++ addSupporter(chainId, i.originCaller)) ++ updateAllBlockIds) | |
510 | + | ((([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(chainHeightKey(chainId), newHeight), StringEntry(chainMetaKey(chainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), setEpochData(i.originCaller), IntegerEntry(chainIdKey(i.originCaller.bytes), chainId), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ mainChainEntry) ++ addSupporter(chainId, i.originCaller)) ++ updateAllBlockIds) | |
508 | 511 | } | |
509 | 512 | else throw("Strict value is not equal to itself.") | |
510 | 513 | } | |
560 | 563 | if ((check == check)) | |
561 | 564 | then { | |
562 | 565 | func filterLeaving (acc,miner) = { | |
563 | - | let $ | |
564 | - | let accMiners = $ | |
565 | - | let isUpdated = $ | |
566 | + | let $t01829418326 = acc | |
567 | + | let accMiners = $t01829418326._1 | |
568 | + | let isUpdated = $t01829418326._2 | |
566 | 569 | if ((miner == newMiner)) | |
567 | 570 | then $Tuple2(accMiners, true) | |
568 | 571 | else $Tuple2((accMiners :+ miner), isUpdated) | |
571 | 574 | let newMiners = if ((size(allMiners) == 0)) | |
572 | 575 | then newMiner | |
573 | 576 | else ((makeString_2C(allMiners, SEP) + SEP) + newMiner) | |
574 | - | let $ | |
577 | + | let $t01859018680 = { | |
575 | 578 | let $l = allLeavingMiners | |
576 | 579 | let $s = size($l) | |
577 | 580 | let $acc0 = $Tuple2(nil, false) | |
585 | 588 | ||
586 | 589 | $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
587 | 590 | } | |
588 | - | let newLeavingMiners = $ | |
589 | - | let isUpdated = $ | |
591 | + | let newLeavingMiners = $t01859018680._1 | |
592 | + | let isUpdated = $t01859018680._2 | |
590 | 593 | let newLeavingMinersAction = if ((newLeavingMiners != nil)) | |
591 | 594 | then [StringEntry(leavingMinersKey(height), makeString_2C(newLeavingMiners, SEP))] | |
592 | 595 | else if ((allLeavingMiners != nil)) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 8 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let INT_MAX = 9223372036854775807 | |
5 | 5 | ||
6 | 6 | let WAVES = 100000000 | |
7 | 7 | ||
8 | 8 | let MIN_BALANCE = (20000 * WAVES) | |
9 | 9 | ||
10 | 10 | let MAX_BLOCKS_AT_EPOCH = 50 | |
11 | 11 | ||
12 | 12 | let SEP = "," | |
13 | 13 | ||
14 | 14 | let BLOCK_HASH_SIZE = 32 | |
15 | 15 | ||
16 | 16 | let ADDRESS_SIZE = 26 | |
17 | 17 | ||
18 | 18 | let MAX_BLOCKS_STR_SIZE = ((64 * MAX_BLOCKS_AT_EPOCH) + (MAX_BLOCKS_AT_EPOCH - 1)) | |
19 | 19 | ||
20 | 20 | let thisEpochDataKey = "thisEpochData" | |
21 | 21 | ||
22 | 22 | let allMinersKey = "allMiners" | |
23 | 23 | ||
24 | 24 | let mainChainIdKey = "mainChainId" | |
25 | 25 | ||
26 | 26 | let lastChainIdKey = "lastChainId" | |
27 | 27 | ||
28 | 28 | let lastEpochBlocksNumberKey = "lastEpochBlocksNumber" | |
29 | 29 | ||
30 | 30 | let minerRewardKey = "minerReward" | |
31 | 31 | ||
32 | 32 | let blockMetaK = "block_0x" | |
33 | 33 | ||
34 | 34 | func pad (i) = { | |
35 | 35 | let s = toString(i) | |
36 | 36 | match size(s) { | |
37 | 37 | case _ => | |
38 | 38 | if ((1 == $match0)) | |
39 | 39 | then ("0000000" + s) | |
40 | 40 | else if ((2 == $match0)) | |
41 | 41 | then ("000000" + s) | |
42 | 42 | else if ((3 == $match0)) | |
43 | 43 | then ("00000" + s) | |
44 | 44 | else if ((4 == $match0)) | |
45 | 45 | then ("0000" + s) | |
46 | 46 | else if ((5 == $match0)) | |
47 | 47 | then ("000" + s) | |
48 | 48 | else if ((6 == $match0)) | |
49 | 49 | then ("00" + s) | |
50 | 50 | else if ((7 == $match0)) | |
51 | 51 | then ("0" + s) | |
52 | 52 | else s | |
53 | 53 | } | |
54 | 54 | } | |
55 | 55 | ||
56 | 56 | ||
57 | 57 | func epochMetaKey (epoch) = ("epoch_" + pad(epoch)) | |
58 | + | ||
59 | + | ||
60 | + | func chainMetaKey (chainId) = ("chain_" + pad(chainId)) | |
58 | 61 | ||
59 | 62 | ||
60 | 63 | let stakingContractAddress = Address(getBinaryValue(this, "stakingContractAddress")) | |
61 | 64 | ||
62 | 65 | func generatingBalance (address) = match getString(stakingContractAddress, ("%s__" + toString(address))) { | |
63 | 66 | case str: String => | |
64 | 67 | let paramList = split(str, "__") | |
65 | 68 | let prevHeight = parseIntValue(paramList[1]) | |
66 | 69 | let prevBalance = parseIntValue(paramList[2]) | |
67 | 70 | let nextHeight = parseIntValue(paramList[3]) | |
68 | 71 | let nextBalance = parseIntValue(paramList[4]) | |
69 | 72 | if ((height >= nextHeight)) | |
70 | 73 | then nextBalance | |
71 | 74 | else if ((height >= prevHeight)) | |
72 | 75 | then prevBalance | |
73 | 76 | else 0 | |
74 | 77 | case _ => | |
75 | 78 | 0 | |
76 | 79 | } | |
77 | 80 | ||
78 | 81 | ||
79 | 82 | func blockMetaKey (blockId) = ("blockMeta" + toBase16String(blockId)) | |
80 | 83 | ||
81 | 84 | ||
82 | 85 | func chainIdKey (generator) = ("chainIdOf" + toBase16String(generator)) | |
83 | 86 | ||
84 | 87 | ||
85 | 88 | func chainHeightKey (chainId) = (("chain" + toString(chainId)) + "Height") | |
86 | 89 | ||
87 | 90 | ||
88 | 91 | func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock") | |
89 | 92 | ||
90 | 93 | ||
91 | 94 | func chainLastBlockIdKey (chainId) = (("chain" + toString(chainId)) + "LastBlock") | |
92 | 95 | ||
93 | 96 | ||
94 | 97 | func chainAllBlockIdsKey (chainId,n) = ((("chain" + toString(chainId)) + "AllBlocks") + toString(n)) | |
95 | 98 | ||
96 | 99 | ||
97 | 100 | func chainAllBlockIdsLastNKey (chainId) = (("chain" + toString(chainId)) + "AllBlocksLastN") | |
98 | 101 | ||
99 | 102 | ||
100 | 103 | func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters") | |
101 | 104 | ||
102 | 105 | ||
103 | 106 | func minerRewardAddress (minerAddr) = (("miner" + minerAddr) + "RewardAddress") | |
104 | 107 | ||
105 | 108 | ||
106 | 109 | func minerJoinHeightKey (minerAddr) = (("miner" + minerAddr) + "JoinHeight") | |
107 | 110 | ||
108 | 111 | ||
109 | 112 | func minerPkKey (rewardAddress) = (("miner" + rewardAddress) + "PK") | |
110 | 113 | ||
111 | 114 | ||
112 | 115 | func leavingMinersKey (epoch) = ("leavingMinersAt" + toString(epoch)) | |
113 | 116 | ||
114 | 117 | ||
115 | 118 | let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0) | |
116 | 119 | ||
117 | 120 | let thisEpochMiner = match getString(thisEpochDataKey) { | |
118 | 121 | case rawThisEpochData: String => | |
119 | 122 | let thisEpochData = split(rawThisEpochData, SEP) | |
120 | 123 | let thisEpoch = parseIntValue(thisEpochData[0]) | |
121 | 124 | if ((thisEpoch == height)) | |
122 | 125 | then fromBase58String(thisEpochData[1]) | |
123 | 126 | else unit | |
124 | 127 | case _ => | |
125 | 128 | unit | |
126 | 129 | } | |
127 | 130 | ||
128 | 131 | let allMiners = match getString(allMinersKey) { | |
129 | 132 | case raw: String => | |
130 | 133 | split_4C(raw, SEP) | |
131 | 134 | case _ => | |
132 | 135 | nil | |
133 | 136 | } | |
134 | 137 | ||
135 | 138 | let allLeavingMiners = match getString(leavingMinersKey(height)) { | |
136 | 139 | case raw: String => | |
137 | 140 | split_4C(raw, SEP) | |
138 | 141 | case _ => | |
139 | 142 | nil | |
140 | 143 | } | |
141 | 144 | ||
142 | 145 | func blockMeta (blockId) = { | |
143 | 146 | let meta = getBinaryValue(blockMetaKey(blockId)) | |
144 | 147 | let metaWithoutHeight = drop(meta, 8) | |
145 | 148 | let metaWithoutHeightEpoch = drop(metaWithoutHeight, 8) | |
146 | 149 | let blockHeight = toInt(take(meta, 8)) | |
147 | 150 | let blockEpoch = toInt(take(metaWithoutHeight, 8)) | |
148 | 151 | let blockParent = take(metaWithoutHeightEpoch, BLOCK_HASH_SIZE) | |
149 | 152 | let blockGenerator = takeRight(meta, ADDRESS_SIZE) | |
150 | 153 | $Tuple4(blockHeight, blockEpoch, blockParent, blockGenerator) | |
151 | 154 | } | |
152 | 155 | ||
153 | 156 | ||
154 | 157 | func setEpochData (generator) = StringEntry(thisEpochDataKey, ((toString(height) + SEP) + toBase58String(generator.bytes))) | |
155 | 158 | ||
156 | 159 | ||
157 | - | let $ | |
160 | + | let $t041315188 = { | |
158 | 161 | let hitSource = match lastBlock.vrf { | |
159 | 162 | case vrf: ByteVector => | |
160 | 163 | vrf | |
161 | 164 | case _ => | |
162 | 165 | lastBlock.generationSignature | |
163 | 166 | } | |
164 | 167 | func processMiner (prev,miner) = { | |
165 | - | let $ | |
166 | - | let prevDelay = $ | |
167 | - | let prevMiner = $ | |
168 | - | let prevTotalBalance = $ | |
169 | - | let prevMiners = $ | |
168 | + | let $t044294492 = prev | |
169 | + | let prevDelay = $t044294492._1 | |
170 | + | let prevMiner = $t044294492._2 | |
171 | + | let prevTotalBalance = $t044294492._3 | |
172 | + | let prevMiners = $t044294492._4 | |
170 | 173 | let minerAddress = addressFromStringValue(miner) | |
171 | 174 | let wavesGenBalance = wavesBalance(minerAddress).generating | |
172 | 175 | let minerBalance = generatingBalance(minerAddress) | |
173 | 176 | if (if (if ((MIN_BALANCE > wavesGenBalance)) | |
174 | 177 | then true | |
175 | 178 | else (0 >= minerBalance)) | |
176 | 179 | then true | |
177 | 180 | else (valueOrElse(getInteger(minerJoinHeightKey(miner)), INT_MAX) > height)) | |
178 | 181 | then prev | |
179 | 182 | else { | |
180 | 183 | let nextDelay = calculateDelay(minerAddress, minerBalance) | |
181 | 184 | if ((prevDelay > nextDelay)) | |
182 | 185 | then $Tuple4(nextDelay, miner, (prevTotalBalance + minerBalance), (prevMiners :+ miner)) | |
183 | 186 | else $Tuple4(prevDelay, prevMiner, (prevTotalBalance + minerBalance), (prevMiners :+ miner)) | |
184 | 187 | } | |
185 | 188 | } | |
186 | 189 | ||
187 | 190 | let $l = (allMiners ++ allLeavingMiners) | |
188 | 191 | let $s = size($l) | |
189 | 192 | let $acc0 = $Tuple4(INT_MAX, "", 0, nil) | |
190 | 193 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
191 | 194 | then $a | |
192 | 195 | else processMiner($a, $l[$i]) | |
193 | 196 | ||
194 | 197 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
195 | 198 | then $a | |
196 | 199 | else throw("List size exceeds 50") | |
197 | 200 | ||
198 | 201 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
199 | 202 | } | |
200 | 203 | ||
201 | - | let computedDelay = $ | |
204 | + | let computedDelay = $t041315188._1 | |
202 | 205 | ||
203 | - | let computedGenerator = $ | |
206 | + | let computedGenerator = $t041315188._2 | |
204 | 207 | ||
205 | - | let computedTotalBalance = $ | |
208 | + | let computedTotalBalance = $t041315188._3 | |
206 | 209 | ||
207 | - | let filteredMiners = $ | |
210 | + | let filteredMiners = $t041315188._4 | |
208 | 211 | ||
209 | 212 | let safeRollbackHeight = { | |
210 | 213 | func addBalance (acc,blockIdStr) = { | |
211 | - | let $ | |
212 | - | let totalBalance = $ | |
213 | - | let prevId = $ | |
214 | - | let generators = $ | |
214 | + | let $t053025346 = acc | |
215 | + | let totalBalance = $t053025346._1 | |
216 | + | let prevId = $t053025346._2 | |
217 | + | let generators = $t053025346._3 | |
215 | 218 | if ((totalBalance > (computedTotalBalance / 2))) | |
216 | 219 | then acc | |
217 | 220 | else { | |
218 | 221 | let blockId = fromBase16String(blockIdStr) | |
219 | 222 | let generator = Address(blockMeta(blockId)._4) | |
220 | 223 | if (containsElement(generators, generator)) | |
221 | 224 | then acc | |
222 | 225 | else { | |
223 | 226 | let balance = generatingBalance(generator) | |
224 | 227 | $Tuple3((totalBalance + balance), blockId, (generators :+ generator)) | |
225 | 228 | } | |
226 | 229 | } | |
227 | 230 | } | |
228 | 231 | ||
229 | 232 | func getBlockIds (n) = { | |
230 | 233 | let rawStr = valueOrElse(getString(chainAllBlockIdsKey(mainChainId, n)), "") | |
231 | 234 | if ((rawStr == "")) | |
232 | 235 | then nil | |
233 | 236 | else split_4C(rawStr, SEP) | |
234 | 237 | } | |
235 | 238 | ||
236 | 239 | let lastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(mainChainId)), 0) | |
237 | 240 | let allBlocksIds = (((getBlockIds(lastN) ++ getBlockIds((lastN - 1))) ++ getBlockIds((lastN - 2))) ++ getBlockIds((lastN - 3))) | |
238 | - | let $ | |
241 | + | let $t061146188 = { | |
239 | 242 | let $l = allBlocksIds | |
240 | 243 | let $s = size($l) | |
241 | 244 | let $acc0 = $Tuple3(0, base58'', nil) | |
242 | 245 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
243 | 246 | then $a | |
244 | 247 | else addBalance($a, $l[$i]) | |
245 | 248 | ||
246 | 249 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
247 | 250 | then $a | |
248 | 251 | else throw("List size exceeds 200") | |
249 | 252 | ||
250 | 253 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100), 101), 102), 103), 104), 105), 106), 107), 108), 109), 110), 111), 112), 113), 114), 115), 116), 117), 118), 119), 120), 121), 122), 123), 124), 125), 126), 127), 128), 129), 130), 131), 132), 133), 134), 135), 136), 137), 138), 139), 140), 141), 142), 143), 144), 145), 146), 147), 148), 149), 150), 151), 152), 153), 154), 155), 156), 157), 158), 159), 160), 161), 162), 163), 164), 165), 166), 167), 168), 169), 170), 171), 172), 173), 174), 175), 176), 177), 178), 179), 180), 181), 182), 183), 184), 185), 186), 187), 188), 189), 190), 191), 192), 193), 194), 195), 196), 197), 198), 199), 200) | |
251 | 254 | } | |
252 | - | let _b = $ | |
253 | - | let blockId = $ | |
255 | + | let _b = $t061146188._1 | |
256 | + | let blockId = $t061146188._2 | |
254 | 257 | blockMeta(blockId)._1 | |
255 | 258 | } | |
256 | 259 | ||
257 | 260 | func supportingBalance (chainId) = { | |
258 | 261 | func addBalance (acc,generatorStr) = { | |
259 | - | let $ | |
260 | - | let totalBalance = $ | |
261 | - | let generators = $ | |
262 | + | let $t063336369 = acc | |
263 | + | let totalBalance = $t063336369._1 | |
264 | + | let generators = $t063336369._2 | |
262 | 265 | let generator = addressFromStringValue(generatorStr) | |
263 | 266 | if (containsElement(generators, generator)) | |
264 | 267 | then acc | |
265 | 268 | else { | |
266 | 269 | let balance = generatingBalance(generator) | |
267 | 270 | $Tuple2((totalBalance + balance), (generators :+ generator)) | |
268 | 271 | } | |
269 | 272 | } | |
270 | 273 | ||
271 | 274 | let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP) | |
272 | - | let $ | |
275 | + | let $t066916756 = { | |
273 | 276 | let $l = allGenerators | |
274 | 277 | let $s = size($l) | |
275 | 278 | let $acc0 = $Tuple2(0, nil) | |
276 | 279 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
277 | 280 | then $a | |
278 | 281 | else addBalance($a, $l[$i]) | |
279 | 282 | ||
280 | 283 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
281 | 284 | then $a | |
282 | 285 | else throw("List size exceeds 100") | |
283 | 286 | ||
284 | 287 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100) | |
285 | 288 | } | |
286 | - | let balance = $ | |
287 | - | let _g = $ | |
289 | + | let balance = $t066916756._1 | |
290 | + | let _g = $t066916756._2 | |
288 | 291 | balance | |
289 | 292 | } | |
290 | 293 | ||
291 | 294 | ||
292 | 295 | func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator)) | |
293 | 296 | then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator)) | |
294 | 297 | else unit | |
295 | 298 | ||
296 | 299 | ||
297 | 300 | func isReferenceCorrect (reference,lastBlock) = match lastBlock { | |
298 | 301 | case _: Unit => | |
299 | 302 | unit | |
300 | 303 | case lb: ByteVector => | |
301 | 304 | if ((reference == lb)) | |
302 | 305 | then unit | |
303 | 306 | else throw(((("Expected a reference to the chain last block: " + toBase16String(lb)) + ". Got: ") + toBase16String(reference))) | |
304 | 307 | case _ => | |
305 | 308 | throw("Match error") | |
306 | 309 | } | |
307 | 310 | ||
308 | 311 | ||
309 | 312 | func chainIsInactive (chainId) = { | |
310 | 313 | let firstBlockId = getBinaryValue(chainFirstBlockIdKey(chainId)) | |
311 | 314 | (safeRollbackHeight > blockMeta(firstBlockId)._1) | |
312 | 315 | } | |
313 | 316 | ||
314 | 317 | ||
315 | 318 | func ensureMainOrInactiveChain (generator) = match getInteger(chainIdKey(generator.bytes)) { | |
316 | 319 | case currentId: Int => | |
317 | 320 | if (if ((currentId == mainChainId)) | |
318 | 321 | then true | |
319 | 322 | else chainIsInactive(currentId)) | |
320 | 323 | then unit | |
321 | 324 | else throw(("miner is mining other chain " + toString(currentId))) | |
322 | 325 | case _ => | |
323 | 326 | unit | |
324 | 327 | } | |
325 | 328 | ||
326 | 329 | ||
327 | 330 | func ensureAltChainExtension (generator,chainId) = match getInteger(chainIdKey(generator.bytes)) { | |
328 | 331 | case currentId: Int => | |
329 | 332 | if ((currentId == chainId)) | |
330 | 333 | then unit | |
331 | 334 | else { | |
332 | 335 | let extendingFirstBlockId = getBinaryValue(chainFirstBlockIdKey(chainId)) | |
333 | 336 | let minerCurrentFirstBlockId = getBinaryValue(chainFirstBlockIdKey(currentId)) | |
334 | 337 | let extendingFirstBlockHeight = blockMeta(extendingFirstBlockId)._1 | |
335 | 338 | let minerCurrentFirstBlockHeight = blockMeta(minerCurrentFirstBlockId)._1 | |
336 | 339 | if ((extendingFirstBlockHeight > minerCurrentFirstBlockHeight)) | |
337 | 340 | then unit | |
338 | 341 | else throw(((((("miner is mining other chain " + toString(currentId)) + ", height of the alt chain first block ") + toString(extendingFirstBlockHeight)) + " is not less than height of the miner active chain first block ") + toString(minerCurrentFirstBlockHeight))) | |
339 | 342 | } | |
340 | 343 | case _ => | |
341 | 344 | unit | |
342 | 345 | } | |
343 | 346 | ||
344 | 347 | ||
345 | 348 | func ensureReferenceIsSafeForRollback (reference) = { | |
346 | 349 | let startHeight = blockMeta(reference)._1 | |
347 | 350 | if ((safeRollbackHeight > startHeight)) | |
348 | 351 | then throw(((("start height " + toString(startHeight)) + " is less than minimum height ") + toString(safeRollbackHeight))) | |
349 | 352 | else unit | |
350 | 353 | } | |
351 | 354 | ||
352 | 355 | ||
353 | 356 | func ensureCorrectEpoch (epoch) = if ((epoch == height)) | |
354 | 357 | then unit | |
355 | 358 | else throw(((("Expected block from epoch " + toString(height)) + ". Got ") + toString(epoch))) | |
356 | 359 | ||
357 | 360 | ||
358 | 361 | func checkBlocksNumber () = if ((MAX_BLOCKS_AT_EPOCH > getIntegerValue(lastEpochBlocksNumberKey))) | |
359 | 362 | then unit | |
360 | 363 | else throw("Max blocks number at epoch reached") | |
361 | 364 | ||
362 | 365 | ||
363 | 366 | func addSupporter (chainId,generator) = { | |
364 | 367 | let supportersStr = getStringValue(supportersKey(chainId)) | |
365 | 368 | let supporters = split(supportersStr, SEP) | |
366 | 369 | if (containsElement(supporters, toString(generator))) | |
367 | 370 | then nil | |
368 | 371 | else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))] | |
369 | 372 | } | |
370 | 373 | ||
371 | 374 | ||
372 | 375 | @Callable(i) | |
373 | 376 | func appendBlock (blockHash,reference) = { | |
374 | 377 | let check = checkBlocksNumber() | |
375 | 378 | if ((check == check)) | |
376 | 379 | then if ((thisEpochMiner != i.originCaller.bytes)) | |
377 | 380 | then match thisEpochMiner { | |
378 | 381 | case epochMiner: ByteVector => | |
379 | 382 | throw(("not allowed to forge blocks in this epoch, expected from " + toBase58String(epochMiner))) | |
380 | 383 | case _ => | |
381 | 384 | throw("not allowed to forge blocks in this epoch, epoch miner is absent") | |
382 | 385 | } | |
383 | 386 | else { | |
384 | 387 | let chainId = valueOrElse(getInteger(chainIdKey(i.originCaller.bytes)), mainChainId) | |
385 | 388 | let lastBlockId = getBinaryValue(chainLastBlockIdKey(chainId)) | |
386 | 389 | let check2 = isReferenceCorrect(reference, lastBlockId) | |
387 | 390 | if ((check2 == check2)) | |
388 | 391 | then { | |
389 | 392 | let chainHeight = valueOrElse(getInteger(chainHeightKey(chainId)), 0) | |
390 | 393 | let newHeight = (chainHeight + 1) | |
391 | 394 | let blocksNumber = valueOrElse(getInteger(lastEpochBlocksNumberKey), 0) | |
392 | 395 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + lastBlockId) + i.originCaller.bytes) | |
393 | - | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(chainId), newHeight), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(lastEpochBlocksNumberKey, (blocksNumber + 1)), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
396 | + | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(chainId), newHeight), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), StringEntry(chainMetaKey(chainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(lastEpochBlocksNumberKey, (blocksNumber + 1)), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
394 | 397 | } | |
395 | 398 | else throw("Strict value is not equal to itself.") | |
396 | 399 | } | |
397 | 400 | else throw("Strict value is not equal to itself.") | |
398 | 401 | } | |
399 | 402 | ||
400 | 403 | ||
401 | 404 | ||
402 | 405 | @Callable(i) | |
403 | 406 | func extendMainChain (blockHash,reference,epoch) = { | |
404 | 407 | let checkEpoch = ensureCorrectEpoch(epoch) | |
405 | 408 | if ((checkEpoch == checkEpoch)) | |
406 | 409 | then { | |
407 | 410 | let checkGenerator = ensureMiningEpoch(i.originCaller) | |
408 | 411 | if ((checkGenerator == checkGenerator)) | |
409 | 412 | then { | |
410 | 413 | let checkChain = ensureMainOrInactiveChain(i.originCaller) | |
411 | 414 | if ((checkChain == checkChain)) | |
412 | 415 | then { | |
413 | 416 | let chainHeight = valueOrElse(getInteger(chainHeightKey(mainChainId)), 0) | |
414 | 417 | let lastValidBlockId = getBinary(chainLastBlockIdKey(mainChainId)) | |
415 | 418 | let checkReference = isReferenceCorrect(reference, lastValidBlockId) | |
416 | 419 | if ((checkReference == checkReference)) | |
417 | 420 | then { | |
418 | 421 | let blockIdsLastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(mainChainId)), 0) | |
419 | 422 | let blockIds = valueOrElse(getString(chainAllBlockIdsKey(mainChainId, blockIdsLastN)), "") | |
420 | 423 | let newHeight = (chainHeight + 1) | |
421 | 424 | let updateAllBlockIds = if ((size(blockIds) >= MAX_BLOCKS_STR_SIZE)) | |
422 | 425 | then [IntegerEntry(chainAllBlockIdsLastNKey(mainChainId), (blockIdsLastN + 1)), StringEntry(chainAllBlockIdsKey(mainChainId, (blockIdsLastN + 1)), toBase16String(blockHash))] | |
423 | 426 | else { | |
424 | 427 | let newBlockIds = if ((blockIds == "")) | |
425 | 428 | then toBase16String(blockHash) | |
426 | 429 | else ((toBase16String(blockHash) + SEP) + blockIds) | |
427 | 430 | [StringEntry(chainAllBlockIdsKey(mainChainId, blockIdsLastN), newBlockIds)] | |
428 | 431 | } | |
429 | 432 | let firstBlockId = match lastValidBlockId { | |
430 | 433 | case id: ByteVector => | |
431 | 434 | nil | |
432 | 435 | case _ => | |
433 | 436 | [BinaryEntry(chainFirstBlockIdKey(mainChainId), blockHash)] | |
434 | 437 | } | |
435 | 438 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
436 | - | (([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(mainChainId), newHeight), BinaryEntry(chainLastBlockIdKey(mainChainId), blockHash), IntegerEntry(chainIdKey(i.originCaller.bytes), mainChainId), setEpochData(i.originCaller), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ firstBlockId) ++ updateAllBlockIds) | |
439 | + | (([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), IntegerEntry(chainHeightKey(mainChainId), newHeight), BinaryEntry(chainLastBlockIdKey(mainChainId), blockHash), StringEntry(chainMetaKey(mainChainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(chainIdKey(i.originCaller.bytes), mainChainId), setEpochData(i.originCaller), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ firstBlockId) ++ updateAllBlockIds) | |
437 | 440 | } | |
438 | 441 | else throw("Strict value is not equal to itself.") | |
439 | 442 | } | |
440 | 443 | else throw("Strict value is not equal to itself.") | |
441 | 444 | } | |
442 | 445 | else throw("Strict value is not equal to itself.") | |
443 | 446 | } | |
444 | 447 | else throw("Strict value is not equal to itself.") | |
445 | 448 | } | |
446 | 449 | ||
447 | 450 | ||
448 | 451 | ||
449 | 452 | @Callable(i) | |
450 | 453 | func startAltChain (blockHash,reference,epoch) = { | |
451 | 454 | let checkEpoch = ensureCorrectEpoch(epoch) | |
452 | 455 | if ((checkEpoch == checkEpoch)) | |
453 | 456 | then { | |
454 | 457 | let checkReference = ensureReferenceIsSafeForRollback(reference) | |
455 | 458 | if ((checkReference == checkReference)) | |
456 | 459 | then { | |
457 | 460 | let checkGenerator = ensureMiningEpoch(i.originCaller) | |
458 | 461 | if ((checkGenerator == checkGenerator)) | |
459 | 462 | then { | |
460 | 463 | let checkChain = ensureMainOrInactiveChain(i.originCaller) | |
461 | 464 | if ((checkChain == checkChain)) | |
462 | 465 | then { | |
463 | 466 | let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1) | |
464 | 467 | let newHeight = (blockMeta(reference)._1 + 1) | |
465 | 468 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
466 | - | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainFirstBlockIdKey(newChainId), blockHash), BinaryEntry(chainLastBlockIdKey(newChainId), blockHash), StringEntry(chainAllBlockIdsKey(newChainId, 0), toBase16String(blockHash)), IntegerEntry(chainHeightKey(newChainId), newHeight), IntegerEntry(chainIdKey(i.originCaller.bytes), newChainId), setEpochData(i.originCaller), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastEpochBlocksNumberKey, 1), IntegerEntry(lastChainIdKey, newChainId), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
469 | + | [BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainFirstBlockIdKey(newChainId), blockHash), BinaryEntry(chainLastBlockIdKey(newChainId), blockHash), StringEntry(chainAllBlockIdsKey(newChainId, 0), toBase16String(blockHash)), IntegerEntry(chainHeightKey(newChainId), newHeight), StringEntry(chainMetaKey(newChainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), IntegerEntry(chainIdKey(i.originCaller.bytes), newChainId), setEpochData(i.originCaller), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastEpochBlocksNumberKey, 1), IntegerEntry(lastChainIdKey, newChainId), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] | |
467 | 470 | } | |
468 | 471 | else throw("Strict value is not equal to itself.") | |
469 | 472 | } | |
470 | 473 | else throw("Strict value is not equal to itself.") | |
471 | 474 | } | |
472 | 475 | else throw("Strict value is not equal to itself.") | |
473 | 476 | } | |
474 | 477 | else throw("Strict value is not equal to itself.") | |
475 | 478 | } | |
476 | 479 | ||
477 | 480 | ||
478 | 481 | ||
479 | 482 | @Callable(i) | |
480 | 483 | func extendAltChain (chainId,blockHash,reference,epoch) = { | |
481 | 484 | let checkEpoch = ensureCorrectEpoch(epoch) | |
482 | 485 | if ((checkEpoch == checkEpoch)) | |
483 | 486 | then { | |
484 | 487 | let checkGenerator = ensureMiningEpoch(i.originCaller) | |
485 | 488 | if ((checkGenerator == checkGenerator)) | |
486 | 489 | then { | |
487 | 490 | let checkChain = ensureAltChainExtension(i.originCaller, chainId) | |
488 | 491 | if ((checkChain == checkChain)) | |
489 | 492 | then { | |
490 | 493 | let checkReference = isReferenceCorrect(reference, getBinary(chainLastBlockIdKey(chainId))) | |
491 | 494 | if ((checkReference == checkReference)) | |
492 | 495 | then { | |
493 | 496 | let chainHeight = valueOrElse(getInteger(chainHeightKey(chainId)), 0) | |
494 | 497 | let blockIdsLastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(chainId)), 0) | |
495 | 498 | let blockIds = getStringValue(chainAllBlockIdsKey(chainId, blockIdsLastN)) | |
496 | 499 | let newHeight = (chainHeight + 1) | |
497 | 500 | let updateAllBlockIds = if ((size(blockIds) >= MAX_BLOCKS_STR_SIZE)) | |
498 | 501 | then [IntegerEntry(chainAllBlockIdsLastNKey(chainId), (blockIdsLastN + 1)), StringEntry(chainAllBlockIdsKey(chainId, (blockIdsLastN + 1)), toBase16String(blockHash))] | |
499 | 502 | else { | |
500 | 503 | let newBlockIds = ((toBase16String(blockHash) + SEP) + blockIds) | |
501 | 504 | [StringEntry(chainAllBlockIdsKey(chainId, blockIdsLastN), newBlockIds)] | |
502 | 505 | } | |
503 | 506 | let mainChainEntry = if ((supportingBalance(chainId) > (computedTotalBalance / 2))) | |
504 | 507 | then [IntegerEntry(mainChainIdKey, chainId)] | |
505 | 508 | else nil | |
506 | 509 | let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes) | |
507 | - | ((([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(chainHeightKey(chainId), newHeight), setEpochData(i.originCaller), IntegerEntry(chainIdKey(i.originCaller.bytes), chainId), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ mainChainEntry) ++ addSupporter(chainId, i.originCaller)) ++ updateAllBlockIds) | |
510 | + | ((([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry((blockMetaK + toBase16String(blockHash)), newBlockMeta), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(chainHeightKey(chainId), newHeight), StringEntry(chainMetaKey(chainId), ((toString(newHeight) + SEP) + toBase16String(blockHash))), setEpochData(i.originCaller), IntegerEntry(chainIdKey(i.originCaller.bytes), chainId), IntegerEntry(lastEpochBlocksNumberKey, 1), StringEntry(epochMetaKey(height), ((toString(i.originCaller) + ",0,") + toBase16String(blockHash)))] ++ mainChainEntry) ++ addSupporter(chainId, i.originCaller)) ++ updateAllBlockIds) | |
508 | 511 | } | |
509 | 512 | else throw("Strict value is not equal to itself.") | |
510 | 513 | } | |
511 | 514 | else throw("Strict value is not equal to itself.") | |
512 | 515 | } | |
513 | 516 | else throw("Strict value is not equal to itself.") | |
514 | 517 | } | |
515 | 518 | else throw("Strict value is not equal to itself.") | |
516 | 519 | } | |
517 | 520 | ||
518 | 521 | ||
519 | 522 | ||
520 | 523 | @Callable(i) | |
521 | 524 | func join (rewardAddress) = { | |
522 | 525 | func checkRewardAddress (address) = match getBinary(minerPkKey(address)) { | |
523 | 526 | case pk: ByteVector => | |
524 | 527 | if ((pk == i.originCallerPublicKey)) | |
525 | 528 | then unit | |
526 | 529 | else throw(((("L2 miner address " + address) + " is already linked with ") + toBase58String(pk))) | |
527 | 530 | case _ => | |
528 | 531 | unit | |
529 | 532 | } | |
530 | 533 | ||
531 | 534 | if ((MIN_BALANCE > wavesBalance(i.originCaller).generating)) | |
532 | 535 | then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE))) | |
533 | 536 | else if ((size(rewardAddress) != 20)) | |
534 | 537 | then throw("rewardAddress should be an L2 address") | |
535 | 538 | else { | |
536 | 539 | func checkExistence (exists,miner) = if (exists) | |
537 | 540 | then true | |
538 | 541 | else (miner == toString(i.originCaller)) | |
539 | 542 | ||
540 | 543 | let alreadyExists = { | |
541 | 544 | let $l = allMiners | |
542 | 545 | let $s = size($l) | |
543 | 546 | let $acc0 = false | |
544 | 547 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
545 | 548 | then $a | |
546 | 549 | else checkExistence($a, $l[$i]) | |
547 | 550 | ||
548 | 551 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
549 | 552 | then $a | |
550 | 553 | else throw("List size exceeds 50") | |
551 | 554 | ||
552 | 555 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
553 | 556 | } | |
554 | 557 | if (alreadyExists) | |
555 | 558 | then nil | |
556 | 559 | else { | |
557 | 560 | let newMiner = toString(i.originCaller) | |
558 | 561 | let rewardAddressHex = toBase16String(rewardAddress) | |
559 | 562 | let check = checkRewardAddress(rewardAddressHex) | |
560 | 563 | if ((check == check)) | |
561 | 564 | then { | |
562 | 565 | func filterLeaving (acc,miner) = { | |
563 | - | let $ | |
564 | - | let accMiners = $ | |
565 | - | let isUpdated = $ | |
566 | + | let $t01829418326 = acc | |
567 | + | let accMiners = $t01829418326._1 | |
568 | + | let isUpdated = $t01829418326._2 | |
566 | 569 | if ((miner == newMiner)) | |
567 | 570 | then $Tuple2(accMiners, true) | |
568 | 571 | else $Tuple2((accMiners :+ miner), isUpdated) | |
569 | 572 | } | |
570 | 573 | ||
571 | 574 | let newMiners = if ((size(allMiners) == 0)) | |
572 | 575 | then newMiner | |
573 | 576 | else ((makeString_2C(allMiners, SEP) + SEP) + newMiner) | |
574 | - | let $ | |
577 | + | let $t01859018680 = { | |
575 | 578 | let $l = allLeavingMiners | |
576 | 579 | let $s = size($l) | |
577 | 580 | let $acc0 = $Tuple2(nil, false) | |
578 | 581 | func $f1_1 ($a,$i) = if (($i >= $s)) | |
579 | 582 | then $a | |
580 | 583 | else filterLeaving($a, $l[$i]) | |
581 | 584 | ||
582 | 585 | func $f1_2 ($a,$i) = if (($i >= $s)) | |
583 | 586 | then $a | |
584 | 587 | else throw("List size exceeds 50") | |
585 | 588 | ||
586 | 589 | $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
587 | 590 | } | |
588 | - | let newLeavingMiners = $ | |
589 | - | let isUpdated = $ | |
591 | + | let newLeavingMiners = $t01859018680._1 | |
592 | + | let isUpdated = $t01859018680._2 | |
590 | 593 | let newLeavingMinersAction = if ((newLeavingMiners != nil)) | |
591 | 594 | then [StringEntry(leavingMinersKey(height), makeString_2C(newLeavingMiners, SEP))] | |
592 | 595 | else if ((allLeavingMiners != nil)) | |
593 | 596 | then [DeleteEntry(leavingMinersKey(height))] | |
594 | 597 | else nil | |
595 | 598 | let joinHeight = if (isUpdated) | |
596 | 599 | then height | |
597 | 600 | else (height + 1) | |
598 | 601 | let deleteOldRewardAddressPk = match getBinary(minerRewardAddress(newMiner)) { | |
599 | 602 | case oldAddress: ByteVector => | |
600 | 603 | if ((oldAddress == rewardAddress)) | |
601 | 604 | then nil | |
602 | 605 | else [DeleteEntry(minerPkKey(toBase16String(oldAddress)))] | |
603 | 606 | case _ => | |
604 | 607 | nil | |
605 | 608 | } | |
606 | 609 | (([StringEntry(allMinersKey, newMiners), IntegerEntry(minerJoinHeightKey(newMiner), joinHeight), BinaryEntry(minerRewardAddress(newMiner), rewardAddress), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ newLeavingMinersAction) ++ deleteOldRewardAddressPk) | |
607 | 610 | } | |
608 | 611 | else throw("Strict value is not equal to itself.") | |
609 | 612 | } | |
610 | 613 | } | |
611 | 614 | } | |
612 | 615 | ||
613 | 616 | ||
614 | 617 | ||
615 | 618 | @Callable(i) | |
616 | 619 | func leave () = { | |
617 | 620 | let leavingMiner = toString(i.originCaller) | |
618 | 621 | func filterMiner (acc,miner) = if ((miner == leavingMiner)) | |
619 | 622 | then acc | |
620 | 623 | else (acc :+ miner) | |
621 | 624 | ||
622 | 625 | let restMiners = { | |
623 | 626 | let $l = allMiners | |
624 | 627 | let $s = size($l) | |
625 | 628 | let $acc0 = nil | |
626 | 629 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
627 | 630 | then $a | |
628 | 631 | else filterMiner($a, $l[$i]) | |
629 | 632 | ||
630 | 633 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
631 | 634 | then $a | |
632 | 635 | else throw("List size exceeds 50") | |
633 | 636 | ||
634 | 637 | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50) | |
635 | 638 | } | |
636 | 639 | if ((thisEpochMiner == i.originCaller.bytes)) | |
637 | 640 | then throw("designated miner can't leave") | |
638 | 641 | else match getInteger(minerJoinHeightKey(leavingMiner)) { | |
639 | 642 | case minerHeight: Int => | |
640 | 643 | if ((minerHeight > height)) | |
641 | 644 | then [StringEntry(allMinersKey, makeString_2C(restMiners, SEP)), DeleteEntry(minerJoinHeightKey(leavingMiner))] | |
642 | 645 | else { | |
643 | 646 | let oldLeavingMiners = valueOrElse(getString(leavingMinersKey(height)), "") | |
644 | 647 | let newLeavingMiners = if ((oldLeavingMiners == "")) | |
645 | 648 | then leavingMiner | |
646 | 649 | else ((oldLeavingMiners + SEP) + leavingMiner) | |
647 | 650 | [StringEntry(allMinersKey, makeString_2C(restMiners, SEP)), DeleteEntry(minerJoinHeightKey(leavingMiner)), StringEntry(leavingMinersKey(height), newLeavingMiners)] | |
648 | 651 | } | |
649 | 652 | case _ => | |
650 | 653 | [StringEntry(allMinersKey, makeString_2C(restMiners, SEP))] | |
651 | 654 | } | |
652 | 655 | } | |
653 | 656 | ||
654 | 657 |
github/deemru/w8io/169f3d6 116.69 ms ◑![]()