code.vegaprotocol.io/vega@v0.79.0/datanode/entities/data_source_spec_test.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 entities_test 17 18 import ( 19 "testing" 20 "time" 21 22 dstypes "code.vegaprotocol.io/vega/core/datasource/common" 23 "code.vegaprotocol.io/vega/datanode/entities" 24 "code.vegaprotocol.io/vega/protos/vega" 25 vegapb "code.vegaprotocol.io/vega/protos/vega" 26 datapb "code.vegaprotocol.io/vega/protos/vega/data/v1" 27 28 "github.com/stretchr/testify/assert" 29 "google.golang.org/protobuf/types/known/structpb" 30 ) 31 32 func TestExternalDataSourceSpecFromProto(t *testing.T) { 33 timeNow := time.Now() 34 timeCreated := timeNow 35 timeUpdated := timeCreated.Add(time.Second) 36 timeNowu := uint64(timeNow.UnixNano()) 37 tHash := entities.TxHash("test-hash") 38 39 t.Run("nil spec", func(t *testing.T) { 40 r := entities.ExternalDataSourceSpecFromProto(nil, tHash, timeNow) 41 42 assert.NotNil(t, r) 43 assert.NotNil(t, r.Spec.Data) 44 assert.Nil(t, r.Spec.Data.DataSourceDefinition) 45 }) 46 47 t.Run("empty spec", func(t *testing.T) { 48 r := entities.ExternalDataSourceSpecFromProto( 49 &vegapb.ExternalDataSourceSpec{}, 50 tHash, 51 timeNow, 52 ) 53 assert.NotNil(t, r.Spec.Data) 54 assert.Nil(t, r.Spec.Data.DataSourceDefinition) 55 assert.Equal(t, entities.TxHash(""), r.Spec.TxHash) 56 }) 57 58 t.Run("non-empty spec but empty data", func(t *testing.T) { 59 s := &vega.DataSourceSpec{ 60 Id: "test-id-0", 61 CreatedAt: timeCreated.UnixNano(), 62 UpdatedAt: timeUpdated.UnixNano(), 63 Data: nil, 64 } 65 66 r := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow) 67 assert.NotNil(t, r.Spec.Data) 68 assert.Nil(t, r.Spec.Data.DataSourceDefinition) 69 assert.Equal(t, r.Spec.ID, entities.SpecID("test-id-0")) 70 assert.Equal(t, r.Spec.CreatedAt.UnixNano(), timeCreated.UnixNano()) 71 assert.Equal(t, r.Spec.UpdatedAt.UnixNano(), timeUpdated.UnixNano()) 72 assert.Equal(t, r.Spec.TxHash, tHash) 73 assert.Equal(t, entities.DataSourceSpecStatus(0), r.Spec.Status) 74 assert.Equal(t, r.Spec.VegaTime, timeNow) 75 }) 76 77 t.Run("with external data definition", func(t *testing.T) { 78 s := &vegapb.DataSourceSpec{ 79 Id: "test-id-1", 80 CreatedAt: timeCreated.UnixNano(), 81 UpdatedAt: timeUpdated.UnixNano(), 82 Data: vegapb.NewDataSourceDefinition( 83 vegapb.DataSourceContentTypeOracle, 84 ).SetOracleConfig( 85 &vega.DataSourceDefinitionExternal_Oracle{ 86 Oracle: &vegapb.DataSourceSpecConfiguration{ 87 Signers: dstypes.SignersIntoProto( 88 []*dstypes.Signer{dstypes.CreateSignerFromString("0xTESTSIGN", dstypes.SignerTypePubKey)}, 89 ), 90 Filters: []*datapb.Filter{ 91 { 92 Key: &datapb.PropertyKey{ 93 Name: "trading.terminated", 94 Type: datapb.PropertyKey_TYPE_BOOLEAN, 95 }, 96 Conditions: []*datapb.Condition{ 97 { 98 Operator: datapb.Condition_OPERATOR_EQUALS, 99 Value: "12", 100 }, 101 }, 102 }, 103 }, 104 }, 105 }, 106 ), 107 } 108 109 r := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow) 110 spec := r.Spec 111 data := spec.Data 112 assert.NotNil(t, spec) 113 assert.NotNil(t, spec.Data.DataSourceDefinition) 114 assert.Equal(t, r.Spec.ID, entities.SpecID("test-id-1")) 115 assert.Equal(t, timeCreated.UnixNano(), r.Spec.CreatedAt.UnixNano()) 116 assert.Equal(t, timeUpdated.UnixNano(), r.Spec.UpdatedAt.UnixNano()) 117 assert.Equal(t, tHash, spec.TxHash) 118 assert.Equal(t, entities.DataSourceSpecStatus(0), spec.Status) 119 assert.Equal(t, r.Spec.VegaTime, timeNow) 120 assert.Nil(t, data.GetInternal()) 121 assert.NotNil(t, data.GetExternal()) 122 123 o := data.GetExternal().GetOracle() 124 signers := o.Signers 125 assert.Equal(t, 1, len(signers)) 126 assert.Equal(t, "0xTESTSIGN", signers[0].GetPubKey().Key) 127 128 filters := o.Filters 129 assert.Equal(t, 1, len(filters)) 130 assert.Equal(t, 1, len(filters[0].Conditions)) 131 assert.Equal(t, datapb.Condition_Operator(1), filters[0].Conditions[0].Operator) 132 assert.Equal(t, "12", filters[0].Conditions[0].Value) 133 assert.Equal(t, "trading.terminated", filters[0].Key.Name) 134 assert.Equal(t, datapb.PropertyKey_TYPE_BOOLEAN, filters[0].Key.Type) 135 }) 136 137 t.Run("with external ethereum data definition", func(t *testing.T) { 138 s := &vegapb.DataSourceSpec{ 139 Id: "test-id-1", 140 CreatedAt: timeCreated.UnixNano(), 141 UpdatedAt: timeUpdated.UnixNano(), 142 Data: vegapb.NewDataSourceDefinition( 143 vegapb.DataSourceContentTypeEthOracle, 144 ).SetOracleConfig( 145 &vega.DataSourceDefinitionExternal_EthOracle{ 146 EthOracle: &vegapb.EthCallSpec{ 147 Address: "test-eth-address", 148 Abi: "5", 149 Method: "test-method", 150 Args: []*structpb.Value{ 151 structpb.NewStringValue("test-arg-value"), 152 }, 153 Trigger: &vegapb.EthCallTrigger{ 154 Trigger: &vegapb.EthCallTrigger_TimeTrigger{ 155 TimeTrigger: &vegapb.EthTimeTrigger{ 156 Initial: &timeNowu, 157 }, 158 }, 159 }, 160 Filters: []*datapb.Filter{ 161 { 162 Key: &datapb.PropertyKey{ 163 Name: "test-key", 164 Type: datapb.PropertyKey_Type(2), 165 }, 166 Conditions: []*datapb.Condition{ 167 { 168 Operator: datapb.Condition_OPERATOR_EQUALS, 169 Value: "12", 170 }, 171 }, 172 }, 173 }, 174 }, 175 }, 176 ), 177 } 178 179 r := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow) 180 spec := r.Spec 181 data := spec.Data 182 assert.NotNil(t, spec) 183 assert.NotNil(t, spec.Data.DataSourceDefinition) 184 assert.Equal(t, r.Spec.ID, entities.SpecID("test-id-1")) 185 assert.Equal(t, timeCreated.UnixNano(), r.Spec.CreatedAt.UnixNano()) 186 assert.Equal(t, timeUpdated.UnixNano(), r.Spec.UpdatedAt.UnixNano()) 187 assert.Equal(t, tHash, spec.TxHash) 188 assert.Equal(t, entities.DataSourceSpecStatus(0), spec.Status) 189 assert.Equal(t, r.Spec.VegaTime, timeNow) 190 assert.Nil(t, data.GetInternal()) 191 assert.NotNil(t, data.GetExternal()) 192 193 o := data.GetExternal().GetEthOracle() 194 assert.NotNil(t, o) 195 196 assert.Equal(t, "test-eth-address", o.Address) 197 assert.Equal(t, string("string_value:\"test-arg-value\""), o.Args[0].String()) 198 assert.Equal(t, string("5"), o.Abi) 199 assert.Equal(t, "test-method", o.Method) 200 filters := o.Filters 201 assert.Equal(t, 1, len(filters)) 202 assert.Equal(t, 1, len(filters[0].Conditions)) 203 assert.Equal(t, datapb.Condition_Operator(1), filters[0].Conditions[0].Operator) 204 assert.Equal(t, "12", filters[0].Conditions[0].Value) 205 assert.Equal(t, "test-key", filters[0].Key.Name) 206 assert.Equal(t, datapb.PropertyKey_TYPE_INTEGER, filters[0].Key.Type) 207 }) 208 209 t.Run("with internal data definition", func(t *testing.T) { 210 s := &vegapb.DataSourceSpec{ 211 Id: "test-id-2", 212 CreatedAt: timeCreated.UnixNano(), 213 UpdatedAt: timeUpdated.UnixNano(), 214 Data: vegapb.NewDataSourceDefinition( 215 vegapb.DataSourceContentTypeInternalTimeTermination, 216 ).SetTimeTriggerConditionConfig( 217 []*datapb.Condition{ 218 { 219 Operator: datapb.Condition_OPERATOR_GREATER_THAN, 220 Value: "12", 221 }, 222 }, 223 ), 224 } 225 226 r := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow) 227 spec := r.Spec 228 data := spec.Data 229 assert.NotNil(t, spec) 230 assert.NotNil(t, spec.Data.DataSourceDefinition) 231 assert.Equal(t, r.Spec.ID, entities.SpecID("test-id-2")) 232 assert.Equal(t, r.Spec.CreatedAt.UnixNano(), timeCreated.UnixNano()) 233 assert.Equal(t, r.Spec.UpdatedAt.UnixNano(), timeUpdated.UnixNano()) 234 assert.Equal(t, tHash, spec.TxHash) 235 assert.Equal(t, entities.DataSourceSpecStatus(0), spec.Status) 236 assert.Equal(t, r.Spec.VegaTime, timeNow) 237 assert.Nil(t, data.GetExternal()) 238 assert.NotNil(t, data.GetInternal()) 239 240 conditions := data.GetInternal().GetTime().Conditions 241 assert.Equal(t, 1, len(conditions)) 242 assert.Equal(t, datapb.Condition_OPERATOR_GREATER_THAN, conditions[0].Operator) 243 assert.Equal(t, "12", conditions[0].Value) 244 }) 245 } 246 247 func TestExternalDataSourceSpecToProto(t *testing.T) { 248 timeNow := time.Now() 249 timeCreated := timeNow 250 timeUpdated := timeCreated.Add(time.Second) 251 tHash := entities.TxHash("test-hash") 252 timeNowu := uint64(timeNow.UnixNano()) 253 254 t.Run("nil spec", func(t *testing.T) { 255 protoSpec := entities.ExternalDataSourceSpecFromProto(nil, tHash, timeNow).ToProto() 256 assert.NotNil(t, protoSpec) 257 }) 258 259 t.Run("empty spec", func(t *testing.T) { 260 protoSpec := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{}, tHash, timeNow).ToProto() 261 assert.NotNil(t, protoSpec) 262 }) 263 264 t.Run("non-empty spec but empty data", func(t *testing.T) { 265 protoSpec := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{ 266 Spec: &vegapb.DataSourceSpec{ 267 Id: "test-id-01", 268 CreatedAt: timeCreated.UnixNano(), 269 UpdatedAt: timeUpdated.UnixNano(), 270 Data: nil, 271 }, 272 }, tHash, timeNow).ToProto() 273 assert.NotNil(t, protoSpec) 274 assert.Equal(t, "", protoSpec.Spec.Id) 275 }) 276 277 t.Run("with external data definition", func(t *testing.T) { 278 s := &vegapb.DataSourceSpec{ 279 Id: "test-id-02", 280 CreatedAt: timeCreated.Unix(), 281 UpdatedAt: timeUpdated.Unix(), 282 Data: vegapb.NewDataSourceDefinition( 283 vegapb.DataSourceContentTypeOracle, 284 ).SetOracleConfig( 285 &vega.DataSourceDefinitionExternal_Oracle{ 286 Oracle: &vegapb.DataSourceSpecConfiguration{ 287 Signers: dstypes.SignersIntoProto( 288 []*dstypes.Signer{dstypes.CreateSignerFromString("0xTESTSIGN", dstypes.SignerTypePubKey)}, 289 ), 290 Filters: []*datapb.Filter{ 291 { 292 Key: &datapb.PropertyKey{ 293 Name: "trading.terminated", 294 Type: datapb.PropertyKey_TYPE_BOOLEAN, 295 }, 296 Conditions: []*datapb.Condition{ 297 { 298 Operator: datapb.Condition_OPERATOR_EQUALS, 299 Value: "12", 300 }, 301 }, 302 }, 303 }, 304 }, 305 }, 306 ), 307 } 308 309 protoResult := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow).ToProto() 310 protoSpec := protoResult.GetSpec() 311 assert.Equal(t, timeCreated.Unix(), protoSpec.CreatedAt) 312 assert.Equal(t, timeUpdated.Unix(), protoSpec.UpdatedAt) 313 314 oracleData := protoSpec.Data.GetExternal() 315 assert.NotNil(t, oracleData.GetOracle()) 316 o := oracleData.GetOracle() 317 assert.Equal(t, 1, len(o.Filters)) 318 assert.NotNil(t, o.GetFilters()) 319 assert.Equal(t, "trading.terminated", o.GetFilters()[0].Key.Name) 320 assert.Equal(t, datapb.PropertyKey_TYPE_BOOLEAN, o.GetFilters()[0].Key.Type) 321 assert.Equal(t, 1, len(o.GetFilters()[0].Conditions)) 322 assert.Equal(t, datapb.Condition_OPERATOR_EQUALS, o.GetFilters()[0].Conditions[0].Operator) 323 assert.Equal(t, "12", o.GetFilters()[0].Conditions[0].Value) 324 assert.NotNil(t, o.GetSigners()) 325 assert.Equal(t, "0xTESTSIGN", o.GetSigners()[0].GetPubKey().Key) 326 }) 327 328 t.Run("with external ethereum spec data definition", func(t *testing.T) { 329 s := &vegapb.DataSourceSpec{ 330 Id: "test-id-02", 331 CreatedAt: timeCreated.Unix(), 332 UpdatedAt: timeUpdated.Unix(), 333 Data: vegapb.NewDataSourceDefinition( 334 vegapb.DataSourceContentTypeEthOracle, 335 ).SetOracleConfig( 336 &vega.DataSourceDefinitionExternal_EthOracle{ 337 EthOracle: &vegapb.EthCallSpec{ 338 Address: "test-eth-address", 339 Abi: "5", 340 Method: "test-method", 341 Args: []*structpb.Value{ 342 structpb.NewStringValue("test-arg-value"), 343 }, 344 Trigger: &vegapb.EthCallTrigger{ 345 Trigger: &vegapb.EthCallTrigger_TimeTrigger{ 346 TimeTrigger: &vegapb.EthTimeTrigger{ 347 Initial: &timeNowu, 348 }, 349 }, 350 }, 351 Filters: []*datapb.Filter{ 352 { 353 Key: &datapb.PropertyKey{ 354 Name: "test-key", 355 Type: datapb.PropertyKey_Type(2), 356 }, 357 Conditions: []*datapb.Condition{ 358 { 359 Operator: datapb.Condition_OPERATOR_EQUALS, 360 Value: "12", 361 }, 362 }, 363 }, 364 }, 365 }, 366 }, 367 ), 368 } 369 370 protoResult := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, timeNow).ToProto() 371 protoSpec := protoResult.GetSpec() 372 assert.Equal(t, timeCreated.Unix(), protoSpec.CreatedAt) 373 assert.Equal(t, timeUpdated.Unix(), protoSpec.UpdatedAt) 374 375 oracleData := protoSpec.Data.GetExternal() 376 assert.NotNil(t, oracleData.GetEthOracle()) 377 o := oracleData.GetEthOracle() 378 assert.NotNil(t, o) 379 assert.Equal(t, "test-eth-address", o.Address) 380 assert.Equal(t, string("string_value:\"test-arg-value\""), o.Args[0].String()) 381 assert.Equal(t, string("5"), o.Abi) 382 assert.Equal(t, "test-method", o.Method) 383 assert.Equal(t, 1, len(o.Filters)) 384 assert.NotNil(t, o.GetFilters()) 385 assert.Equal(t, "test-key", o.GetFilters()[0].Key.Name) 386 assert.Equal(t, datapb.PropertyKey_TYPE_INTEGER, o.GetFilters()[0].Key.Type) 387 assert.Equal(t, 1, len(o.GetFilters()[0].Conditions)) 388 assert.Equal(t, datapb.Condition_OPERATOR_EQUALS, o.GetFilters()[0].Conditions[0].Operator) 389 assert.Equal(t, "12", o.GetFilters()[0].Conditions[0].Value) 390 }) 391 392 t.Run("with internal data definition", func(t *testing.T) { 393 s := &vegapb.DataSourceSpec{ 394 CreatedAt: timeCreated.Unix(), 395 UpdatedAt: timeUpdated.Unix(), 396 Data: vegapb.NewDataSourceDefinition( 397 vegapb.DataSourceContentTypeInternalTimeTermination, 398 ).SetTimeTriggerConditionConfig( 399 []*datapb.Condition{ 400 { 401 Operator: datapb.Condition_OPERATOR_GREATER_THAN, 402 Value: "12", 403 }, 404 }, 405 ), 406 } 407 408 r := entities.ExternalDataSourceSpecFromProto(&vegapb.ExternalDataSourceSpec{Spec: s}, tHash, time.Now()) 409 protoResult := r.ToProto() 410 protoSpec := protoResult.GetSpec() 411 assert.Equal(t, timeCreated.Unix(), protoSpec.CreatedAt) 412 assert.Equal(t, timeUpdated.Unix(), protoSpec.UpdatedAt) 413 414 timeTermData := protoSpec.Data.GetInternal() 415 assert.NotNil(t, timeTermData) 416 timeTerms := timeTermData.GetTime() 417 assert.Equal(t, 1, len(timeTerms.Conditions)) 418 assert.Equal(t, datapb.Condition_OPERATOR_GREATER_THAN, timeTerms.Conditions[0].Operator) 419 assert.Equal(t, "12", timeTerms.Conditions[0].Value) 420 }) 421 }