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  }