code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_oracle_spec.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package steps 17 18 import ( 19 "errors" 20 "fmt" 21 "time" 22 23 dstypes "code.vegaprotocol.io/vega/core/datasource/common" 24 "code.vegaprotocol.io/vega/core/integration/steps/market" 25 "code.vegaprotocol.io/vega/libs/ptr" 26 vgrand "code.vegaprotocol.io/vega/libs/rand" 27 protoTypes "code.vegaprotocol.io/vega/protos/vega" 28 datav1 "code.vegaprotocol.io/vega/protos/vega/data/v1" 29 30 "github.com/cucumber/godog" 31 ) 32 33 func TheOracleSpec(config *market.Config, name string, specType string, rawPubKeys string, table *godog.Table) error { 34 pubKeys := StrSlice(rawPubKeys, ",") 35 pubKeysSigners := make([]*datav1.Signer, len(pubKeys)) 36 for i, s := range pubKeys { 37 pks := dstypes.CreateSignerFromString(s, dstypes.SignerTypePubKey) 38 pubKeysSigners[i] = pks.IntoProto() 39 } 40 41 binding := &protoTypes.DataSourceSpecToFutureBinding{} 42 43 rows := parseOracleSpecTable(table) 44 filters := make([]*datav1.Filter, 0, len(rows)) 45 for _, r := range rows { 46 row := oracleSpecRow{row: r} 47 var numDec *uint64 48 decimals, ok := row.propertyDecimals() 49 if ok { 50 numDec = ptr.From(decimals) 51 } 52 filter := &datav1.Filter{ 53 Key: &datav1.PropertyKey{ 54 Name: row.propertyName(), 55 Type: row.propertyType(), 56 NumberDecimalPlaces: numDec, 57 }, 58 Conditions: []*datav1.Condition{}, 59 } 60 61 if r.HasColumn("condition") != r.HasColumn("value") { 62 return errors.New("condition and value columns require each other") 63 } 64 65 if r.HasColumn("condition") { 66 value := row.value() 67 68 if row.propertyType() == datav1.PropertyKey_TYPE_TIMESTAMP { 69 expiry, err := time.Parse(time.RFC3339, value) 70 if err != nil { 71 panic(fmt.Errorf("cannot parse expiry condition: %w", err)) 72 } 73 value = fmt.Sprintf("%d", expiry.Unix()) 74 } 75 76 filter.Conditions = append(filter.Conditions, 77 &datav1.Condition{ 78 Operator: row.condition(), 79 Value: value, 80 }, 81 ) 82 } 83 84 filters = append(filters, filter) 85 86 if row.destination() == "settlement data" { 87 binding.SettlementDataProperty = row.propertyName() 88 } 89 if row.destination() == "trading termination" { 90 binding.TradingTerminationProperty = row.propertyName() 91 } 92 } 93 94 return config.OracleConfigs.Add( 95 name, 96 specType, 97 &protoTypes.DataSourceSpec{ 98 Id: vgrand.RandomStr(10), 99 Data: protoTypes.NewDataSourceDefinition( 100 protoTypes.DataSourceContentTypeOracle, 101 ).SetOracleConfig( 102 &protoTypes.DataSourceDefinitionExternal_Oracle{ 103 Oracle: &protoTypes.DataSourceSpecConfiguration{ 104 Signers: pubKeysSigners, 105 Filters: filters, 106 }, 107 }, 108 ), 109 }, 110 binding, 111 ) 112 } 113 114 func parseOracleSpecTable(table *godog.Table) []RowWrapper { 115 return StrictParseTable(table, []string{ 116 "property", 117 "type", 118 "binding", 119 }, []string{ 120 "decimals", 121 "condition", 122 "value", 123 }) 124 } 125 126 type oracleSpecRow struct { 127 row RowWrapper 128 } 129 130 func (r oracleSpecRow) propertyName() string { 131 return r.row.MustStr("property") 132 } 133 134 func (r oracleSpecRow) propertyType() datav1.PropertyKey_Type { 135 return r.row.MustOracleSpecPropertyType("type") 136 } 137 138 func (r oracleSpecRow) propertyDecimals() (uint64, bool) { 139 return r.row.U64B("decimals") 140 } 141 142 func (r oracleSpecRow) destination() string { 143 return r.row.MustStr("binding") 144 } 145 146 func (r oracleSpecRow) condition() datav1.Condition_Operator { 147 return r.row.MustOracleSpecConditionOperator("condition") 148 } 149 150 func (r oracleSpecRow) value() string { 151 return r.row.MustStr("value") 152 }