tx · 4hpWgf1YuT8kw6JJE85jdP3pTtCwtkiRDgdhCMzYG4fm 3MyAeWKH4gAS6iDvTRo42Rz3WCoMEi63WMC: -0.01400000 Waves 2020.10.26 22:34 [1237994] smart account 3MyAeWKH4gAS6iDvTRo42Rz3WCoMEi63WMC > SELF 0.00000000 Waves
{ "type": 13, "id": "4hpWgf1YuT8kw6JJE85jdP3pTtCwtkiRDgdhCMzYG4fm", "fee": 1400000, "feeAssetId": null, "timestamp": 1603740903050, "version": 1, "sender": "3MyAeWKH4gAS6iDvTRo42Rz3WCoMEi63WMC", "senderPublicKey": "7c9cqT2Lt6fXSVvQwScRZDjnVcpPYhsbxSkh21LEzdY3", "proofs": [ "3WDqTMZnwoBBrGhQmdF4CpApQzaiefUZmbXMJpjBJAbMB2chpdjV6ydxMYd65uhNo3rCHKpfFa7smxK5F6gxg9jw" ], "script": "base64:AAIEAAAAAAAAAAwIAhIICgYICAICAgIAAAAeAAAAAANTRVACAAAAAl9fAQAAAAprZXlGYWN0b3J5AAAAAAIAAAALJXNfX2ZhY3RvcnkBAAAACGtleVByaWNlAAAAAQAAAAxjdXJyZW5jeUNvZGUJAAEsAAAAAgIAAAANJXMlc19fcHJpY2VfXwUAAAAMY3VycmVuY3lDb2RlAQAAAA9rZXlQcmljZUZhaWx1cmUAAAABAAAADGN1cnJlbmN5Q29kZQkABLkAAAACCQAETAAAAAICAAAAGyVzJXMlZF9fZmluYWxpemF0aW9uRmFpbHVyZQkABEwAAAACBQAAAAxjdXJyZW5jeUNvZGUJAARMAAAAAgkAAaQAAAABBQAAAAZoZWlnaHQFAAAAA25pbAUAAAADU0VQAQAAAA1rZXlMYXN0SGVpZ2h0AAAAAQAAAAxjdXJyZW5jeUNvZGUJAAEsAAAAAgIAAAASJXMlc19fbGFzdEhlaWdodF9fBQAAAAxjdXJyZW5jeUNvZGUBAAAAEGtleVByaWNlQnlIZWlnaHQAAAACAAAADGN1cnJlbmN5Q29kZQAAAAFoCQAEuQAAAAIJAARMAAAAAgIAAAAVJXMlcyVkX19wcmljZUJ5SGVpZ2h0CQAETAAAAAIFAAAADGN1cnJlbmN5Q29kZQkABEwAAAACCQABpAAAAAEFAAAAAWgFAAAAA25pbAUAAAADU0VQAQAAAAZrZXlJZHgAAAABAAAADGN1cnJlbmN5Q29kZQkAASwAAAACAgAAABIlcyVzX19pZHhDdXJyZW50X18FAAAADGN1cnJlbmN5Q29kZQEAAAANa2V5SWR4MkhlaWdodAAAAAIAAAAMY3VycmVuY3lDb2RlAAAAA2lkeAkABLkAAAACCQAETAAAAAICAAAAEiVzJXMlZF9faWR4MkhlaWdodAkABEwAAAACBQAAAAxjdXJyZW5jeUNvZGUJAARMAAAAAgkAAaQAAAABBQAAAANpZHgFAAAAA25pbAUAAAADU0VQAQAAAA1rZXlIZWlnaHQySWR4AAAAAgAAAAxjdXJyZW5jeUNvZGUAAAABaAkABLkAAAACCQAETAAAAAICAAAAEiVzJXMlZF9faGVpZ2h0MklkeAkABEwAAAACBQAAAAxjdXJyZW5jeUNvZGUJAARMAAAAAgkAAaQAAAABBQAAAAFoBQAAAANuaWwFAAAAA1NFUAEAAAARa2V5R3JvdXBGaW5TdGF0dXMAAAACAAAACGdyb3VwTnVtAAAADGZpbkhlaWdodFN0cgkABLkAAAACCQAETAAAAAICAAAAFiVzJWQlZF9fZ3JvdXBGaW5TdGF0dXMJAARMAAAAAgUAAAAIZ3JvdXBOdW0JAARMAAAAAgUAAAAMZmluSGVpZ2h0U3RyBQAAAANuaWwFAAAAA1NFUAEAAAARa2V5SXNNYXJrZXRPcGVuZWQAAAABAAAADGN1cnJlbmN5Q29kZQkAASwAAAACAgAAABYlcyVzX19pc01hcmtldE9wZW5lZF9fBQAAAAxjdXJyZW5jeUNvZGUBAAAADGtleUdyb3VwRGF0YQAAAAEAAAAIZ3JvdXBOdW0JAAEsAAAAAgIAAAANJXMlZF9fZ3JvdXBfXwUAAAAIZ3JvdXBOdW0BAAAAEGtleUVtcHR5UHJpY2VNc2cAAAABAAAACHBvc2l0aW9uCQAEuQAAAAIJAARMAAAAAgIAAAAVJXMlZCVkX19lbXB0eVByaWNlTXNnCQAETAAAAAIJAAGkAAAAAQUAAAAGaGVpZ2h0CQAETAAAAAIJAAGkAAAAAQUAAAAIcG9zaXRpb24FAAAAA25pbAUAAAADU0VQAQAAAAxrZXlJc0Jsb2NrZWQAAAAAAgAAAA0lc19faXNCbG9ja2VkAQAAABJrZXlJc0Jsb2NrZWRTZW5kZXIAAAAAAgAAABclcyVzX19pc0Jsb2NrZWRfX3NlbmRlcgEAAAASa2V5SXNCbG9ja2VkUmVhc29uAAAAAAIAAAAXJXMlc19faXNCbG9ja2VkX19yZWFzb24BAAAACmtleU9yYWNsZXMAAAAAAgAAABUlcyVzX19jb25maWdfX29yYWNsZXMBAAAAEmtleUJsYWNrU3dhcm1QcmljZQAAAAEAAAABaAkAASwAAAACAgAAACQlcyVzJWRfX2lzQmxvY2tlZF9fYmxhY2tTd2FybVByaWNlX18JAAGkAAAAAQUAAAABaAEAAAARaXNHcm91cEZpbmFsYWl6ZWQAAAACAAAACGdyb3VwTnVtAAAADGZpbkhlaWdodFN0cgkBAAAACWlzRGVmaW5lZAAAAAEJAAQbAAAAAgUAAAAEdGhpcwkBAAAAEWtleUdyb3VwRmluU3RhdHVzAAAAAgUAAAAIZ3JvdXBOdW0FAAAADGZpbkhlaWdodFN0cgEAAAATcmVhZEdyb3VwRGF0YU9yRmFpbAAAAAEAAAAIZ3JvdXBOdW0EAAAAAWsJAQAAAAxrZXlHcm91cERhdGEAAAABBQAAAAhncm91cE51bQQAAAAMZ3JvdXBEYXRhT3B0CQAEHQAAAAIFAAAABHRoaXMFAAAAAWsDCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAAMZ3JvdXBEYXRhT3B0CQEAAAAFdmFsdWUAAAABBQAAAAxncm91cERhdGFPcHQJAAACAAAAAQkAASwAAAACAgAAABllbXB0eSBncm91cCBkYXRhIGZvciBrZXk9BQAAAAFrAAAAAAlpc0Jsb2NrZWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgUAAAAEdGhpcwkBAAAADGtleUlzQmxvY2tlZAAAAAAHAAAAAA5taW5QcmljZXNDb3VudAAAAAAAAAAAAwAAAAAScGVyY2VudFByaWNlT2Zmc2V0AAAAAAAAAAAFAAAAABFwdWJLZXlPcmFjbGVzTGlzdAkABLUAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzCQEAAAAKa2V5T3JhY2xlcwAAAAACAAAAASwAAAAAC29yYWNsZUNvdW50CQABkAAAAAEFAAAAEXB1YktleU9yYWNsZXNMaXN0AQAAAB50aHJvd0ludmFsaWRGaW5hbGl6YXRpb25IZWlnaHQAAAABAAAADGZpbkhlaWdodFN0cgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACRpbnZhbGlkIGZpbmFsaXphdGlvbiBoZWlnaHQ6IGhlaWdodD0JAAGkAAAAAQUAAAAGaGVpZ2h0AgAAABQgZmluYWxpemF0aW9uSGVpZ2h0PQUAAAAMZmluSGVpZ2h0U3RyAQAAABp0aHJvd0dyb3VwQWxyZWFkeUZpbmFsaXplZAAAAAIAAAAIZ3JvdXBOdW0AAAAMZmluSGVpZ2h0U3RyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAUcHJpY2VzIGZvciBncm91cE51bT0FAAAACGdyb3VwTnVtAgAAAAQgYXQgBQAAAAxmaW5IZWlnaHRT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dGFTdHIFAAAAA25pbAAAAAEAAAABaQEAAAAWZmluYWxpemVDdXJyZW50UHJpY2VWMgAAAAYAAAAGaGVhZGVyAAAAA21zZwAAAAZzaWduczAAAAAGc2lnbnMxAAAABnNpZ25zMgAAAAZzaWduczMEAAAAC2hlYWRlckFycmF5CQAEtQAAAAIFAAAABmhlYWRlcgIAAAABXwQAAAAIZ3JvdXBOdW0JAAGRAAAAAgUAAAALaGVhZGVyQXJyYXkAAAAAAAAAAAEEAAAADGZpbkhlaWdodFN0cgkAAZEAAAACBQAAAAtoZWFkZXJBcnJheQAAAAAAAAAAAgQAAAAJZmluSGVpZ2h0CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEFAAAADGZpbkhlaWdodFN0cgQAAAALc2lnbnNMZW5ndGgJAABoAAAAAgAAAAAAAAAAQAUAAAALb3JhY2xlQ291bnQDCQEAAAACIT0AAAACBQAAAAZoZWlnaHQFAAAACWZpbkhlaWdodAkBAAAAHnRocm93SW52YWxpZEZpbmFsaXphdGlvbkhlaWdodAAAAAEFAAAADGZpbkhlaWdodFN0cgMJAQAAABFpc0dyb3VwRmluYWxhaXplZAAAAAIFAAAACGdyb3VwTnVtBQAAAAxmaW5IZWlnaHRTdHIJAQAAABp0aHJvd0dyb3VwQWxyZWFkeUZpbmFsaXplZAAAAAIFAAAACGdyb3VwTnVtBQAAAAxmaW5IZWlnaHRTdHIDCQEAAAACIT0AAAACCQABkQAAAAIFAAAAEXB1YktleU9yYWNsZXNMaXN0CQAAagAAAAIFAAAABmhlaWdodAUAAAALb3JhY2xlQ291bnQJAAJYAAAAAQgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQEAAAAadGhyb3dPdXRPZlR1cm5GaW5hbGl6YXRpb24AAAAAAwkBAAAAAiE9AAAAAgkAAMgAAAABBQAAAAZzaWduczAFAAAAC3NpZ25zTGVuZ3RoCQEAAAAcdGhyb3dJbnZhbGlkU2lnbnNQYXJhbUxlbmd0aAAAAAIAAAAAAAAAAAAFAAAABnNpZ25zMAMJAQAAAAIhPQAAAAIJAADIAAAAAQUAAAAGc2lnbnMxBQAAAAtzaWduc0xlbmd0aAkBAAAAHHRocm93SW52YWxpZFNpZ25zUGFyYW1MZW5ndGgAAAACAAAAAAAAAAABBQAAAAZzaWduczEDCQEAAAACIT0AAAACCQAAyAAAAAEFAAAABnNpZ25zMgUAAAALc2lnbnNMZW5ndGgJAQAAABx0aHJvd0ludmFsaWRTaWduc1BhcmFtTGVuZ3RoAAAAAgAAAAAAAAAAAgUAAAAGc2lnbnMyAwkBAAAAAiE9AAAAAgkAAMgAAAABBQAAAAZzaWduczMFAAAAC3NpZ25zTGVuZ3RoCQEAAAAcdGhyb3dJbnZhbGlkU2lnbnNQYXJhbUxlbmd0aAAAAAIAAAAAAAAAAAMFAAAABnNpZ25zMwQAAAAMZ3JvdXBEYXRhS2V5CQEAAAAMa2V5R3JvdXBEYXRhAAAAAQUAAAAIZ3JvdXBOdW0EAAAADGdyb3VwRGF0YVN0cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADGdyb3VwRGF0YUtleQkAASwAAAACAgAAABllbXB0eSBncm91cCBkYXRhIGZvciBrZXk9BQAAAAxncm91cERhdGFLZXkEAAAACG1zZ0FycmF5CQAEtQAAAAIFAAAAA21zZwIAAAABXwMJAQAAAAIhPQAAAAIJAABqAAAAAgkAAZAAAAABBQAAAAhtc2dBcnJheQAAAAAAAAAAAwAAAAAAAAAAAAkAAAIAAAABCQABLAAAAAICAAAAOm1zZyBwYXJhbWV0ZXJzIGNvdW50IG11c3QgYmUgbXVsdGlwbGUgb2YgMzogbXNnQXJyYXkuc2l6ZT0JAAGkAAAAAQkAATEAAAABBQAAAANtc2cJAARNAAAAAgkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAAFWZpbmFsaXplUHJpY2VWMkNvbW1vbgAAAAUAAAAAAAAAAAAFAAAACGdyb3VwTnVtBQAAAAxncm91cERhdGFTdHIFAAAACG1zZ0FycmF5BQAAAAZzaWduczAJAQAAABVmaW5hbGl6ZVByaWNlVjJDb21tb24AAAAFAAAAAAAAAAABBQAAAAhncm91cE51bQUAAAAMZ3JvdXBEYXRhU3RyBQAAAAhtc2dBcnJheQUAAAAGc2lnbnMxCQEAAAAVZmluYWxpemVQcmljZVYyQ29tbW9uAAAABQAAAAAAAAAAAgUAAAAIZ3JvdXBOdW0FAAAADGdyb3VwRGF0YVN0cgUAAAAIbXNnQXJyYXkFAAAABnNpZ25zMgkBAAAAFWZpbmFsaXplUHJpY2VWMkNvbW1vbgAAAAUAAAAAAAAAAAMFAAAACGdyb3VwTnVtBQAAAAxncm91cERhdGFTdHIFAAAACG1zZ0FycmF5BQAAAAZzaWduczMJAQAAAAxCb29sZWFuRW50cnkAAAACCQEAAAARa2V5R3JvdXBGaW5TdGF0dXMAAAACBQAAAAhncm91cE51bQUAAAAMZmluSGVpZ2h0U3RyBgAAAADSlktI", "chainId": 84, "height": 1237994, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HEsHmpMqcXx39qLDte2PMwSkQXsn5VkcjfxFrgHfpZqi Next: none Diff:
Old | New | Differences | |
---|---|---|---|
90 | 90 | ||
91 | 91 | func finalizePriceV2Common (position,groupNum,groupDataStr,msgArray,signs) = { | |
92 | 92 | let msgOffset = (position * 3) | |
93 | - | if ((msgOffset > size(msgArray))) | |
93 | + | if ((msgOffset >= size(msgArray))) | |
94 | 94 | then [StringEntry(keyEmptyPriceMsg(position), "price data is empty")] | |
95 | 95 | else { | |
96 | 96 | let currencyCode = msgArray[(msgOffset + 0)] |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let SEP = "__" | |
5 | 5 | ||
6 | 6 | func keyFactory () = "%s__factory" | |
7 | 7 | ||
8 | 8 | ||
9 | 9 | func keyPrice (currencyCode) = ("%s%s__price__" + currencyCode) | |
10 | 10 | ||
11 | 11 | ||
12 | 12 | func keyPriceFailure (currencyCode) = makeString(["%s%s%d__finalizationFailure", currencyCode, toString(height)], SEP) | |
13 | 13 | ||
14 | 14 | ||
15 | 15 | func keyLastHeight (currencyCode) = ("%s%s__lastHeight__" + currencyCode) | |
16 | 16 | ||
17 | 17 | ||
18 | 18 | func keyPriceByHeight (currencyCode,h) = makeString(["%s%s%d__priceByHeight", currencyCode, toString(h)], SEP) | |
19 | 19 | ||
20 | 20 | ||
21 | 21 | func keyIdx (currencyCode) = ("%s%s__idxCurrent__" + currencyCode) | |
22 | 22 | ||
23 | 23 | ||
24 | 24 | func keyIdx2Height (currencyCode,idx) = makeString(["%s%s%d__idx2Height", currencyCode, toString(idx)], SEP) | |
25 | 25 | ||
26 | 26 | ||
27 | 27 | func keyHeight2Idx (currencyCode,h) = makeString(["%s%s%d__height2Idx", currencyCode, toString(h)], SEP) | |
28 | 28 | ||
29 | 29 | ||
30 | 30 | func keyGroupFinStatus (groupNum,finHeightStr) = makeString(["%s%d%d__groupFinStatus", groupNum, finHeightStr], SEP) | |
31 | 31 | ||
32 | 32 | ||
33 | 33 | func keyIsMarketOpened (currencyCode) = ("%s%s__isMarketOpened__" + currencyCode) | |
34 | 34 | ||
35 | 35 | ||
36 | 36 | func keyGroupData (groupNum) = ("%s%d__group__" + groupNum) | |
37 | 37 | ||
38 | 38 | ||
39 | 39 | func keyEmptyPriceMsg (position) = makeString(["%s%d%d__emptyPriceMsg", toString(height), toString(position)], SEP) | |
40 | 40 | ||
41 | 41 | ||
42 | 42 | func keyIsBlocked () = "%s__isBlocked" | |
43 | 43 | ||
44 | 44 | ||
45 | 45 | func keyIsBlockedSender () = "%s%s__isBlocked__sender" | |
46 | 46 | ||
47 | 47 | ||
48 | 48 | func keyIsBlockedReason () = "%s%s__isBlocked__reason" | |
49 | 49 | ||
50 | 50 | ||
51 | 51 | func keyOracles () = "%s%s__config__oracles" | |
52 | 52 | ||
53 | 53 | ||
54 | 54 | func keyBlackSwarmPrice (h) = ("%s%s%d__isBlocked__blackSwarmPrice__" + toString(h)) | |
55 | 55 | ||
56 | 56 | ||
57 | 57 | func isGroupFinalaized (groupNum,finHeightStr) = isDefined(getBoolean(this, keyGroupFinStatus(groupNum, finHeightStr))) | |
58 | 58 | ||
59 | 59 | ||
60 | 60 | func readGroupDataOrFail (groupNum) = { | |
61 | 61 | let k = keyGroupData(groupNum) | |
62 | 62 | let groupDataOpt = getString(this, k) | |
63 | 63 | if (isDefined(groupDataOpt)) | |
64 | 64 | then value(groupDataOpt) | |
65 | 65 | else throw(("empty group data for key=" + k)) | |
66 | 66 | } | |
67 | 67 | ||
68 | 68 | ||
69 | 69 | let isBlocked = valueOrElse(getBoolean(this, keyIsBlocked()), false) | |
70 | 70 | ||
71 | 71 | let minPricesCount = 3 | |
72 | 72 | ||
73 | 73 | let percentPriceOffset = 5 | |
74 | 74 | ||
75 | 75 | let pubKeyOraclesList = split(getStringValue(this, keyOracles()), ",") | |
76 | 76 | ||
77 | 77 | let oracleCount = size(pubKeyOraclesList) | |
78 | 78 | ||
79 | 79 | func throwInvalidFinalizationHeight (finHeightStr) = throw(((("invalid finalization height: height=" + toString(height)) + " finalizationHeight=") + finHeightStr)) | |
80 | 80 | ||
81 | 81 | ||
82 | 82 | func throwGroupAlreadyFinalized (groupNum,finHeightStr) = throw((((("prices for groupNum=" + groupNum) + " at ") + finHeightStr) + " height have been already finalized")) | |
83 | 83 | ||
84 | 84 | ||
85 | 85 | func throwInvalidSignsParamLength (num,param) = throw(((((("invalid signs" + toString(num)) + " parameter: actual.size=") + toString(size(param))) + " base58Val=") + toBase58String(param))) | |
86 | 86 | ||
87 | 87 | ||
88 | 88 | func throwOutOfTurnFinalization () = throw(((("Out of turn finalization: " + toString(height)) + " block should be finalize by ") + pubKeyOraclesList[(height % oracleCount)])) | |
89 | 89 | ||
90 | 90 | ||
91 | 91 | func finalizePriceV2Common (position,groupNum,groupDataStr,msgArray,signs) = { | |
92 | 92 | let msgOffset = (position * 3) | |
93 | - | if ((msgOffset > size(msgArray))) | |
93 | + | if ((msgOffset >= size(msgArray))) | |
94 | 94 | then [StringEntry(keyEmptyPriceMsg(position), "price data is empty")] | |
95 | 95 | else { | |
96 | 96 | let currencyCode = msgArray[(msgOffset + 0)] | |
97 | 97 | let newPriceStr = msgArray[(msgOffset + 1)] | |
98 | 98 | let isMarketOpenedStr = msgArray[(msgOffset + 2)] | |
99 | 99 | let newPriceOpt = parseInt(newPriceStr) | |
100 | 100 | let isMarketOpenedOpt = parseInt(isMarketOpenedStr) | |
101 | 101 | let sig0 = take(signs, 64) | |
102 | 102 | let sig1 = take(drop(signs, 64), 64) | |
103 | 103 | let sig2 = take(drop(signs, 128), 64) | |
104 | 104 | let sig3 = take(drop(signs, 192), 64) | |
105 | 105 | let sig4 = takeRightBytes(signs, 64) | |
106 | 106 | if (contains(groupDataStr, currencyCode)) | |
107 | 107 | then if (if (isDefined(newPriceOpt)) | |
108 | 108 | then isDefined(isMarketOpenedOpt) | |
109 | 109 | else false) | |
110 | 110 | then { | |
111 | 111 | let newPrice = value(newPriceOpt) | |
112 | 112 | let isMarketOpened = if ((value(isMarketOpenedOpt) == 1)) | |
113 | 113 | then true | |
114 | 114 | else false | |
115 | 115 | let priceMsgStr = makeString(["WAVES:DEFO:PROTOCOL:PRICE:V002", groupNum, toString(height), currencyCode, newPriceStr, isMarketOpenedStr], "_") | |
116 | 116 | let priceMsg = toBytes(priceMsgStr) | |
117 | 117 | let verificationsCount = (((((if (sigVerify_8Kb(priceMsg, sig0, fromBase58String(pubKeyOraclesList[0]))) | |
118 | 118 | then 1 | |
119 | 119 | else 0) + (if (sigVerify_8Kb(priceMsg, sig1, fromBase58String(pubKeyOraclesList[1]))) | |
120 | 120 | then 1 | |
121 | 121 | else 0)) + (if (sigVerify_8Kb(priceMsg, sig2, fromBase58String(pubKeyOraclesList[2]))) | |
122 | 122 | then 1 | |
123 | 123 | else 0)) + (if (sigVerify_8Kb(priceMsg, sig3, fromBase58String(pubKeyOraclesList[3]))) | |
124 | 124 | then 1 | |
125 | 125 | else 0)) + (if (sigVerify_8Kb(priceMsg, sig4, fromBase58String(pubKeyOraclesList[4]))) | |
126 | 126 | then 1 | |
127 | 127 | else 0)) | |
128 | 128 | if ((verificationsCount >= 3)) | |
129 | 129 | then { | |
130 | 130 | let price = valueOrElse(getInteger(this, keyPrice(currencyCode)), 0) | |
131 | 131 | let idx = valueOrElse(getInteger(this, keyIdx(currencyCode)), 0) | |
132 | 132 | if (if ((price != 0)) | |
133 | 133 | then if ((newPrice >= (price + ((price * 5) / 100)))) | |
134 | 134 | then true | |
135 | 135 | else ((price - ((price * 5) / 100)) >= newPrice) | |
136 | 136 | else false) | |
137 | 137 | then { | |
138 | 138 | let reason = "automatic emergency shutdown because of large price variability" | |
139 | 139 | [BooleanEntry(keyIsBlocked(), true), StringEntry(keyIsBlockedSender(), toString(this)), StringEntry(keyIsBlockedReason(), reason), IntegerEntry(keyBlackSwarmPrice(height), newPrice)] | |
140 | 140 | } | |
141 | 141 | else { | |
142 | 142 | let newIdx = (idx + 1) | |
143 | 143 | [IntegerEntry(keyPrice(currencyCode), newPrice), IntegerEntry(keyLastHeight(currencyCode), height), IntegerEntry(keyPriceByHeight(currencyCode, height), newPrice), IntegerEntry(keyIdx(currencyCode), newIdx), IntegerEntry(keyIdx2Height(currencyCode, newIdx), height), IntegerEntry(keyHeight2Idx(currencyCode, height), newIdx), BooleanEntry(keyIsMarketOpened(currencyCode), isMarketOpened)] | |
144 | 144 | } | |
145 | 145 | } | |
146 | 146 | else [StringEntry(keyPriceFailure(currencyCode), ((((((((("verificationsCount = " + toString(verificationsCount)) + "signs0.length=") + toString(size(signs))) + " msg0 = ") + priceMsgStr) + " sig0 = ") + toBase58String(sig0)) + " key0 = ") + pubKeyOraclesList[0]))] | |
147 | 147 | } | |
148 | 148 | else [StringEntry(keyPriceFailure(currencyCode), ((("data parsing error: newPrice=" + newPriceStr) + " isMarketOpened=") + isMarketOpenedStr))] | |
149 | 149 | else [StringEntry(keyPriceFailure(currencyCode), ((currencyCode + " doesn't exist in group: groupDataStr=") + groupDataStr))] | |
150 | 150 | } | |
151 | 151 | } | |
152 | 152 | ||
153 | 153 | ||
154 | 154 | @Callable(i) | |
155 | 155 | func finalizeCurrentPriceV2 (header,msg,signs0,signs1,signs2,signs3) = { | |
156 | 156 | let headerArray = split(header, "_") | |
157 | 157 | let groupNum = headerArray[1] | |
158 | 158 | let finHeightStr = headerArray[2] | |
159 | 159 | let finHeight = parseIntValue(finHeightStr) | |
160 | 160 | let signsLength = (64 * oracleCount) | |
161 | 161 | if ((height != finHeight)) | |
162 | 162 | then throwInvalidFinalizationHeight(finHeightStr) | |
163 | 163 | else if (isGroupFinalaized(groupNum, finHeightStr)) | |
164 | 164 | then throwGroupAlreadyFinalized(groupNum, finHeightStr) | |
165 | 165 | else if ((pubKeyOraclesList[(height % oracleCount)] != toBase58String(i.callerPublicKey))) | |
166 | 166 | then throwOutOfTurnFinalization() | |
167 | 167 | else if ((size(signs0) != signsLength)) | |
168 | 168 | then throwInvalidSignsParamLength(0, signs0) | |
169 | 169 | else if ((size(signs1) != signsLength)) | |
170 | 170 | then throwInvalidSignsParamLength(1, signs1) | |
171 | 171 | else if ((size(signs2) != signsLength)) | |
172 | 172 | then throwInvalidSignsParamLength(2, signs2) | |
173 | 173 | else if ((size(signs3) != signsLength)) | |
174 | 174 | then throwInvalidSignsParamLength(3, signs3) | |
175 | 175 | else { | |
176 | 176 | let groupDataKey = keyGroupData(groupNum) | |
177 | 177 | let groupDataStr = valueOrErrorMessage(getString(this, groupDataKey), ("empty group data for key=" + groupDataKey)) | |
178 | 178 | let msgArray = split(msg, "_") | |
179 | 179 | if (((size(msgArray) % 3) != 0)) | |
180 | 180 | then throw(("msg parameters count must be multiple of 3: msgArray.size=" + toString(size(msg)))) | |
181 | 181 | else ((((finalizePriceV2Common(0, groupNum, groupDataStr, msgArray, signs0) ++ finalizePriceV2Common(1, groupNum, groupDataStr, msgArray, signs1)) ++ finalizePriceV2Common(2, groupNum, groupDataStr, msgArray, signs2)) ++ finalizePriceV2Common(3, groupNum, groupDataStr, msgArray, signs3)) :+ BooleanEntry(keyGroupFinStatus(groupNum, finHeightStr), true)) | |
182 | 182 | } | |
183 | 183 | } | |
184 | 184 | ||
185 | 185 |
github/deemru/w8io/3ef1775 58.78 ms ◑