github.com/aergoio/aergo@v1.3.1/types/receipt.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"math/big"
    10  	"reflect"
    11  	"strconv"
    12  
    13  	"github.com/aergoio/aergo/internal/enc"
    14  	"github.com/aergoio/aergo/internal/merkle"
    15  	"github.com/gogo/protobuf/jsonpb"
    16  	"github.com/minio/sha256-simd"
    17  	"github.com/willf/bloom"
    18  )
    19  
    20  const (
    21  	successStatus = iota
    22  	createdStatus
    23  	errorStatus
    24  	recreatedStatus
    25  )
    26  
    27  func NewReceipt(contractAddress []byte, status string, jsonRet string) *Receipt {
    28  	return &Receipt{
    29  		ContractAddress: contractAddress[:33],
    30  		Status:          status,
    31  		Ret:             jsonRet,
    32  	}
    33  }
    34  
    35  func (r *Receipt) marshalBody(b *bytes.Buffer, isMerkle bool) error {
    36  	l := make([]byte, 8)
    37  	b.Write(r.ContractAddress)
    38  	var status byte
    39  	switch r.Status {
    40  	case "SUCCESS":
    41  		status = successStatus
    42  	case "CREATED":
    43  		status = createdStatus
    44  	case "ERROR":
    45  		status = errorStatus
    46  	case "RECREATED":
    47  		status = recreatedStatus
    48  	default:
    49  		return errors.New("unsupported status in receipt")
    50  	}
    51  	b.WriteByte(status)
    52  	if !isMerkle || status != errorStatus {
    53  		binary.LittleEndian.PutUint32(l[:4], uint32(len(r.Ret)))
    54  		b.Write(l[:4])
    55  		b.WriteString(r.Ret)
    56  	}
    57  	b.Write(r.TxHash)
    58  
    59  	binary.LittleEndian.PutUint32(l[:4], uint32(len(r.FeeUsed)))
    60  	b.Write(l[:4])
    61  	b.Write(r.FeeUsed)
    62  	binary.LittleEndian.PutUint32(l[:4], uint32(len(r.CumulativeFeeUsed)))
    63  	b.Write(l[:4])
    64  	b.Write(r.CumulativeFeeUsed)
    65  	if len(r.Bloom) == 0 {
    66  		b.WriteByte(0)
    67  	} else {
    68  		b.WriteByte(1)
    69  		b.Write(r.Bloom)
    70  	}
    71  	binary.LittleEndian.PutUint32(l[:4], uint32(len(r.Events)))
    72  	b.Write(l[:4])
    73  
    74  	return nil
    75  }
    76  
    77  func (r *Receipt) marshalStoreBinary() ([]byte, error) {
    78  	var b bytes.Buffer
    79  
    80  	err := r.marshalBody(&b, false)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	for _, ev := range r.Events {
    85  		evB, err := ev.marshalStoreBinary(r)
    86  		if err != nil {
    87  			return nil, err
    88  		}
    89  		b.Write(evB)
    90  	}
    91  
    92  	return b.Bytes(), nil
    93  }
    94  
    95  func (r *Receipt) unmarshalBody(data []byte) ([]byte, uint32) {
    96  	r.ContractAddress = data[:33]
    97  	status := data[33]
    98  	switch status {
    99  	case successStatus:
   100  		r.Status = "SUCCESS"
   101  	case createdStatus:
   102  		r.Status = "CREATED"
   103  	case errorStatus:
   104  		r.Status = "ERROR"
   105  	case recreatedStatus:
   106  		r.Status = "RECREATED"
   107  	}
   108  	pos := uint32(34)
   109  	l := binary.LittleEndian.Uint32(data[pos:])
   110  	pos += 4
   111  	r.Ret = string(data[pos : pos+l])
   112  	pos += l
   113  	r.TxHash = data[pos : pos+32]
   114  	pos += 32
   115  	l = binary.LittleEndian.Uint32(data[pos:])
   116  	pos += 4
   117  	r.FeeUsed = data[pos : pos+l]
   118  	pos += l
   119  	l = binary.LittleEndian.Uint32(data[pos:])
   120  	pos += 4
   121  	r.CumulativeFeeUsed = data[pos : pos+l]
   122  	pos += l
   123  	bloomCheck := data[pos]
   124  	pos += 1
   125  	if bloomCheck == 1 {
   126  		r.Bloom = data[pos : pos+BloomBitByte]
   127  		pos += BloomBitByte
   128  	}
   129  	pos += l
   130  	evCount := binary.LittleEndian.Uint32(data[pos:])
   131  
   132  	return data[pos+4:], evCount
   133  }
   134  
   135  func (r *Receipt) unmarshalStoreBinary(data []byte) ([]byte, error) {
   136  	evData, evCount := r.unmarshalBody(data)
   137  
   138  	r.Events = make([]*Event, evCount)
   139  	var err error
   140  	for i := uint32(0); i < evCount; i++ {
   141  		var ev Event
   142  		evData, err = ev.unmarshalStoreBinary(evData, r)
   143  		if err != nil {
   144  			return nil, err
   145  		}
   146  		r.Events[i] = &ev
   147  	}
   148  	return evData, nil
   149  }
   150  
   151  func (r *Receipt) MarshalBinary() ([]byte, error) {
   152  	var b bytes.Buffer
   153  
   154  	err := r.marshalBody(&b, false)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	for _, ev := range r.Events {
   159  		evB, err := ev.MarshalBinary()
   160  		if err != nil {
   161  			return nil, err
   162  		}
   163  		b.Write(evB)
   164  	}
   165  
   166  	return b.Bytes(), nil
   167  }
   168  
   169  func (r *Receipt) MarshalMerkleBinary() ([]byte, error) {
   170  	var b bytes.Buffer
   171  
   172  	err := r.marshalBody(&b, true)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  
   177  	for _, ev := range r.Events {
   178  		evB, err := ev.MarshalMerkleBinary()
   179  		if err != nil {
   180  			return nil, err
   181  		}
   182  		b.Write(evB)
   183  	}
   184  
   185  	return b.Bytes(), nil
   186  }
   187  
   188  func (r *Receipt) UnmarshalBinary(data []byte) error {
   189  	_, err := r.ReadFrom(data)
   190  	return err
   191  }
   192  
   193  func (r *Receipt) ReadFrom(data []byte) ([]byte, error) {
   194  	evData, evCount := r.unmarshalBody(data)
   195  
   196  	r.Events = make([]*Event, evCount)
   197  	var err error
   198  	for i := uint32(0); i < evCount; i++ {
   199  		var ev Event
   200  		evData, err = ev.UnmarshalBinary(evData)
   201  		if err != nil {
   202  			return nil, err
   203  		}
   204  		r.Events[i] = &ev
   205  	}
   206  	return evData, nil
   207  }
   208  
   209  func (r *Receipt) MarshalJSONPB(*jsonpb.Marshaler) ([]byte, error) {
   210  	return json.Marshal(r)
   211  }
   212  
   213  func (r *Receipt) MarshalJSON() ([]byte, error) {
   214  	var b bytes.Buffer
   215  	b.WriteString(`{"BlokNo":`)
   216  	b.WriteString(fmt.Sprintf("%d", r.BlockNo))
   217  	b.WriteString(`,"BlockHash":"`)
   218  	b.WriteString(enc.ToString(r.BlockHash))
   219  	b.WriteString(`","contractAddress":"`)
   220  	b.WriteString(EncodeAddress(r.ContractAddress))
   221  	b.WriteString(`","status":"`)
   222  	b.WriteString(r.Status)
   223  	if len(r.Ret) == 0 {
   224  		b.WriteString(`","ret": {}`)
   225  	} else if r.Status == "ERROR" {
   226  		js, _ := json.Marshal(r.Ret)
   227  		b.WriteString(`","ret": `)
   228  		b.WriteString(string(js))
   229  	} else {
   230  		b.WriteString(`","ret": `)
   231  		b.WriteString(r.Ret)
   232  	}
   233  	b.WriteString(`,"txHash":"`)
   234  	b.WriteString(enc.ToString(r.TxHash))
   235  	b.WriteString(`","txIndex":`)
   236  	b.WriteString(fmt.Sprintf("%d", r.TxIndex))
   237  	b.WriteString(`,"from":"`)
   238  	b.WriteString(EncodeAddress(r.From))
   239  	b.WriteString(`","to":"`)
   240  	b.WriteString(EncodeAddress(r.To))
   241  	b.WriteString(`","usedFee":`)
   242  	b.WriteString(new(big.Int).SetBytes(r.FeeUsed).String())
   243  	b.WriteString(`,"events":[`)
   244  	for i, ev := range r.Events {
   245  		if i != 0 {
   246  			b.WriteString(`,`)
   247  		}
   248  		bEv, err := ev.MarshalJSON()
   249  		if err != nil {
   250  			return nil, err
   251  		}
   252  		b.Write(bEv)
   253  	}
   254  	b.WriteString(`]}`)
   255  	return b.Bytes(), nil
   256  }
   257  
   258  func (r *Receipt) GetHash() []byte {
   259  	h := sha256.New()
   260  	b, _ := r.MarshalMerkleBinary()
   261  	h.Write(b)
   262  	return h.Sum(nil)
   263  }
   264  
   265  func (r *Receipt) BloomFilter(fi *FilterInfo) bool {
   266  	if r.Bloom == nil {
   267  		return false
   268  	}
   269  
   270  	var buffer bytes.Buffer
   271  	l := make([]byte, 8)
   272  	binary.BigEndian.PutUint64(l, BloomBitBits)
   273  	buffer.Write(l)
   274  	binary.BigEndian.PutUint64(l, BloomHashKNum)
   275  	buffer.Write(l)
   276  	binary.BigEndian.PutUint64(l, BloomBitBits)
   277  	buffer.Write(l)
   278  	buffer.Write(r.Bloom)
   279  
   280  	var bf bloom.BloomFilter
   281  	_, err := bf.ReadFrom(&buffer)
   282  	if err != nil {
   283  		return true
   284  	}
   285  
   286  	if bf.Test(fi.ContractAddress) || bf.Test([]byte(fi.EventName)) {
   287  		return true
   288  	}
   289  	return false
   290  }
   291  
   292  func (r *Receipt) SetMemoryInfo(blkHash []byte, blkNo BlockNo, txIdx int32) {
   293  	r.BlockNo = blkNo
   294  	r.BlockHash = blkHash
   295  	r.TxIndex = txIdx
   296  
   297  	for _, e := range r.Events {
   298  		e.SetMemoryInfo(r, blkHash, blkNo, txIdx)
   299  	}
   300  }
   301  
   302  type bloomFilter bloom.BloomFilter
   303  
   304  func (bf *bloomFilter) GetHash() []byte {
   305  	h := sha256.New()
   306  	b, _ := ((*bloom.BloomFilter)(bf)).GobEncode()
   307  	h.Write(b)
   308  	return h.Sum(nil)
   309  }
   310  
   311  type Receipts struct {
   312  	bloom    *bloomFilter
   313  	receipts []*Receipt
   314  }
   315  
   316  func (rs *Receipts) Get() []*Receipt {
   317  	if rs == nil {
   318  		return nil
   319  	}
   320  	return rs.receipts
   321  }
   322  
   323  func (rs *Receipts) Set(receipts []*Receipt) {
   324  	rs.receipts = receipts
   325  }
   326  
   327  const BloomBitByte = 256
   328  const BloomBitBits = BloomBitByte * 8
   329  const BloomHashKNum = 3
   330  
   331  func (rs *Receipts) MergeBloom(bf *bloom.BloomFilter) error {
   332  	if rs.bloom == nil {
   333  		rs.bloom = (*bloomFilter)(bloom.New(BloomBitBits, BloomHashKNum))
   334  	}
   335  
   336  	return (*bloom.BloomFilter)(rs.bloom).Merge(bf)
   337  }
   338  
   339  func (rs *Receipts) BloomFilter(fi *FilterInfo) bool {
   340  	if rs.bloom == nil {
   341  		return false
   342  	}
   343  	bf := (*bloom.BloomFilter)(rs.bloom)
   344  	if bf.Test(fi.ContractAddress) || bf.Test([]byte(fi.EventName)) {
   345  		return true
   346  	}
   347  	return false
   348  }
   349  
   350  func (rs *Receipts) MerkleRoot() []byte {
   351  	if rs == nil {
   352  		return merkle.CalculateMerkleRoot(nil)
   353  	}
   354  	rsSize := len(rs.receipts)
   355  	if rs.bloom != nil {
   356  		rsSize++
   357  	}
   358  	mes := make([]merkle.MerkleEntry, rsSize)
   359  	for i, r := range rs.receipts {
   360  		mes[i] = r
   361  	}
   362  	if rs.bloom != nil {
   363  		mes[rsSize-1] = rs.bloom
   364  	}
   365  	return merkle.CalculateMerkleRoot(mes)
   366  }
   367  
   368  func (rs *Receipts) MarshalBinary() ([]byte, error) {
   369  	var b bytes.Buffer
   370  	l := make([]byte, 4)
   371  
   372  	if rs.bloom != nil {
   373  		b.WriteByte(1)
   374  		bloomB, err := (*bloom.BloomFilter)(rs.bloom).GobEncode()
   375  		if err != nil {
   376  			return nil, err
   377  		}
   378  		b.Write(bloomB[24:])
   379  	} else {
   380  		b.WriteByte(0)
   381  	}
   382  	binary.LittleEndian.PutUint32(l, uint32(len(rs.receipts)))
   383  	b.Write(l)
   384  	for _, r := range rs.receipts {
   385  		rB, err := r.marshalStoreBinary()
   386  		if err != nil {
   387  			return nil, err
   388  		}
   389  		b.Write(rB)
   390  	}
   391  
   392  	return b.Bytes(), nil
   393  }
   394  
   395  func (rs *Receipts) UnmarshalBinary(data []byte) error {
   396  	checkBloom := data[0]
   397  	pos := 1
   398  	if checkBloom == 1 {
   399  		var buffer bytes.Buffer
   400  		var bf bloom.BloomFilter
   401  		l := make([]byte, 8)
   402  		binary.BigEndian.PutUint64(l, BloomBitBits)
   403  		buffer.Write(l)
   404  		binary.BigEndian.PutUint64(l, BloomHashKNum)
   405  		buffer.Write(l)
   406  		binary.BigEndian.PutUint64(l, BloomBitBits)
   407  		buffer.Write(l)
   408  		buffer.Write(data[pos : pos+BloomBitByte])
   409  		_, err := bf.ReadFrom(&buffer)
   410  		if err != nil {
   411  			return err
   412  		}
   413  		pos += BloomBitByte
   414  		rs.bloom = (*bloomFilter)(&bf)
   415  	}
   416  	rCount := binary.LittleEndian.Uint32(data[pos:])
   417  	pos += 4
   418  	rs.receipts = make([]*Receipt, rCount)
   419  	unread := data[pos:]
   420  	var err error
   421  	for i := uint32(0); i < rCount; i++ {
   422  		var r Receipt
   423  		unread, err = r.unmarshalStoreBinary(unread)
   424  		if err != nil {
   425  			return err
   426  		}
   427  		rs.receipts[i] = &r
   428  	}
   429  	return nil
   430  }
   431  
   432  func (ev *Event) marshalCommonBinary(b *bytes.Buffer) {
   433  	l := make([]byte, 4)
   434  	b.Write(ev.ContractAddress)
   435  	binary.LittleEndian.PutUint32(l, uint32(len(ev.EventName)))
   436  	b.Write(l)
   437  	b.WriteString(ev.EventName)
   438  
   439  	binary.LittleEndian.PutUint32(l, uint32(len(ev.JsonArgs)))
   440  	b.Write(l)
   441  	b.WriteString(ev.JsonArgs)
   442  
   443  	b.Write(ev.TxHash)
   444  
   445  	binary.LittleEndian.PutUint32(l, uint32(ev.EventIdx))
   446  	b.Write(l)
   447  }
   448  
   449  func (ev *Event) MarshalBinary() ([]byte, error) {
   450  	var b bytes.Buffer
   451  	l := make([]byte, 8)
   452  	ev.marshalCommonBinary(&b)
   453  
   454  	b.Write(ev.BlockHash)
   455  	binary.LittleEndian.PutUint64(l[:], ev.BlockNo)
   456  	b.Write(l)
   457  	binary.LittleEndian.PutUint32(l[:4], uint32(ev.TxIndex))
   458  	b.Write(l[:4])
   459  	return b.Bytes(), nil
   460  }
   461  
   462  func (ev *Event) marshalStoreBinary(r *Receipt) ([]byte, error) {
   463  	var b bytes.Buffer
   464  	l := make([]byte, 4)
   465  	if bytes.Equal(r.ContractAddress, ev.ContractAddress) {
   466  		b.WriteByte(0)
   467  	} else {
   468  		b.Write(ev.ContractAddress)
   469  	}
   470  	binary.LittleEndian.PutUint32(l, uint32(len(ev.EventName)))
   471  	b.Write(l)
   472  	b.WriteString(ev.EventName)
   473  
   474  	binary.LittleEndian.PutUint32(l, uint32(len(ev.JsonArgs)))
   475  	b.Write(l)
   476  	b.WriteString(ev.JsonArgs)
   477  
   478  	binary.LittleEndian.PutUint32(l, uint32(ev.EventIdx))
   479  	b.Write(l)
   480  	return b.Bytes(), nil
   481  }
   482  
   483  func (ev *Event) unmarshalStoreBinary(data []byte, r *Receipt) ([]byte, error) {
   484  	var pos uint32
   485  	if data[0] == 0 {
   486  		ev.ContractAddress = r.ContractAddress
   487  		pos += 1
   488  	} else {
   489  		ev.ContractAddress = data[:33]
   490  		pos += 33
   491  	}
   492  	l := binary.LittleEndian.Uint32(data[pos:])
   493  	pos += 4
   494  	ev.EventName = string(data[pos : pos+l])
   495  	pos += l
   496  
   497  	l = binary.LittleEndian.Uint32(data[pos:])
   498  	pos += 4
   499  	ev.JsonArgs = string(data[pos : pos+l])
   500  	pos += l
   501  
   502  	ev.EventIdx = int32(binary.LittleEndian.Uint32(data[pos:]))
   503  	pos += 4
   504  
   505  	return data[pos:], nil
   506  }
   507  
   508  func (ev *Event) MarshalMerkleBinary() ([]byte, error) {
   509  	var b bytes.Buffer
   510  	ev.marshalCommonBinary(&b)
   511  	return b.Bytes(), nil
   512  }
   513  
   514  func (ev *Event) UnmarshalBinary(data []byte) ([]byte, error) {
   515  	pos := uint32(33)
   516  	ev.ContractAddress = data[:pos]
   517  
   518  	l := binary.LittleEndian.Uint32(data[33:])
   519  	pos += 4
   520  	ev.EventName = string(data[pos : pos+l])
   521  	pos += l
   522  
   523  	l = binary.LittleEndian.Uint32(data[pos:])
   524  	pos += 4
   525  	ev.JsonArgs = string(data[pos : pos+l])
   526  	pos += l
   527  
   528  	ev.TxHash = data[pos : pos+32]
   529  	pos += 32
   530  
   531  	ev.EventIdx = int32(binary.LittleEndian.Uint32(data[pos:]))
   532  	pos += 4
   533  
   534  	ev.BlockHash = data[pos : pos+32]
   535  	pos += 32
   536  
   537  	ev.BlockNo = binary.LittleEndian.Uint64(data[pos:])
   538  	pos += 8
   539  
   540  	ev.TxIndex = int32(binary.LittleEndian.Uint32(data[pos:]))
   541  
   542  	return data[pos+4:], nil
   543  }
   544  
   545  func (ev *Event) MarshalJSON() ([]byte, error) {
   546  	var b bytes.Buffer
   547  	b.WriteString(`{"contractAddress":"`)
   548  	b.WriteString(EncodeAddress(ev.ContractAddress))
   549  	b.WriteString(`","eventName":"`)
   550  	b.WriteString(ev.EventName)
   551  	b.WriteString(`","Args":`)
   552  	b.WriteString(ev.JsonArgs)
   553  	b.WriteString(`,"txHash":"`)
   554  	b.WriteString(enc.ToString(ev.TxHash))
   555  	b.WriteString(`","EventIdx":`)
   556  	b.WriteString(fmt.Sprintf("%d", ev.EventIdx))
   557  	b.WriteString(`,"BlockHash":"`)
   558  	b.WriteString(enc.ToString(ev.BlockHash))
   559  	b.WriteString(`","BlockNo":`)
   560  	b.WriteString(fmt.Sprintf("%d", ev.BlockNo))
   561  	b.WriteString(`,"TxIndex":`)
   562  	b.WriteString(fmt.Sprintf("%d", ev.TxIndex))
   563  	b.WriteString(`}`)
   564  	return b.Bytes(), nil
   565  }
   566  
   567  func (ev *Event) SetMemoryInfo(receipt *Receipt, blkHash []byte, blkNo BlockNo, txIdx int32) {
   568  	ev.TxHash = receipt.TxHash
   569  	ev.TxIndex = txIdx
   570  	ev.BlockHash = blkHash
   571  	ev.BlockNo = blkNo
   572  }
   573  
   574  func checkSameArray(value []interface{}, check []interface{}) bool {
   575  	if len(value) != len(check) {
   576  		return false
   577  	}
   578  	for i, v := range value {
   579  		if checkValue(v, check[i]) == false {
   580  			return false
   581  		}
   582  	}
   583  	return true
   584  }
   585  
   586  func checkSameMap(value map[string]interface{}, check map[string]interface{}) bool {
   587  	if len(value) != len(check) {
   588  		return false
   589  	}
   590  	for k, v := range value {
   591  		if checkValue(v, check[k]) == false {
   592  			return false
   593  		}
   594  	}
   595  	return true
   596  }
   597  
   598  func checkValue(value interface{}, check interface{}) bool {
   599  	if reflect.TypeOf(value) != reflect.TypeOf(check) {
   600  		return false
   601  	}
   602  	switch value.(type) {
   603  	case string:
   604  		if value.(string) != check.(string) {
   605  			return false
   606  		}
   607  	case float64:
   608  		if value.(float64) != check.(float64) {
   609  			return false
   610  		}
   611  	case bool:
   612  		if value.(bool) != check.(bool) {
   613  			return false
   614  		}
   615  	case json.Number:
   616  		if value.(json.Number) != check.(json.Number) {
   617  			return false
   618  		}
   619  	case nil:
   620  		return true
   621  	case []interface{}:
   622  		return checkSameArray(value.([]interface{}), check.([]interface{}))
   623  	case map[string]interface{}:
   624  		return checkSameMap(value.(map[string]interface{}), check.(map[string]interface{}))
   625  	default:
   626  		return false
   627  	}
   628  
   629  	return true
   630  }
   631  
   632  func (ev *Event) Filter(filter *FilterInfo, argFilter []ArgFilter) bool {
   633  	if filter.ContractAddress != nil && !bytes.Equal(ev.ContractAddress, filter.ContractAddress) {
   634  		return false
   635  	}
   636  	if len(filter.EventName) != 0 && ev.EventName != filter.EventName {
   637  		return false
   638  	}
   639  	if argFilter != nil {
   640  		var args []interface{}
   641  		err := json.Unmarshal([]byte(ev.JsonArgs), &args)
   642  		if err != nil {
   643  			return false
   644  		}
   645  		argLen := len(args)
   646  		for _, filter := range argFilter {
   647  			if filter.argNo >= argLen {
   648  				return false
   649  			}
   650  			value := args[filter.argNo]
   651  			check := filter.value
   652  			if checkValue(value, check) == false {
   653  				return false
   654  			}
   655  		}
   656  	}
   657  	ev.ContractAddress = AddressOrigin(ev.ContractAddress)
   658  	return true
   659  }
   660  
   661  type ArgFilter struct {
   662  	argNo int
   663  	value interface{}
   664  }
   665  
   666  const MAXBLOCKRANGE = 10000
   667  const padprefix = 0x80
   668  
   669  func AddressPadding(addr []byte) []byte {
   670  	id := make([]byte, AddressLength)
   671  	id[0] = padprefix
   672  	copy(id[1:], addr)
   673  	return id
   674  }
   675  func AddressOrigin(addr []byte) []byte {
   676  	if addr[0] == padprefix {
   677  		addr = addr[1:bytes.IndexByte(addr, 0)]
   678  	}
   679  	return addr
   680  }
   681  
   682  func (fi *FilterInfo) ValidateCheck(to uint64) error {
   683  	if fi.ContractAddress == nil {
   684  		return errors.New("invalid contractAddress:" + string(fi.ContractAddress))
   685  	}
   686  	if len(fi.ContractAddress) < AddressLength {
   687  		fi.ContractAddress = AddressPadding(fi.ContractAddress)
   688  	} else if len(fi.ContractAddress) != AddressLength {
   689  		return errors.New("invalid contractAddress:" + string(fi.ContractAddress))
   690  	}
   691  	if fi.RecentBlockCnt > 0 {
   692  		if fi.RecentBlockCnt > MAXBLOCKRANGE {
   693  			return errors.New(fmt.Sprintf("too large value at recentBlockCnt %d (max %d)",
   694  				fi.RecentBlockCnt, MAXBLOCKRANGE))
   695  		}
   696  
   697  	} else {
   698  		if fi.Blockfrom+MAXBLOCKRANGE < to {
   699  			return errors.New(fmt.Sprintf("too large block range(max %d) from %d to %d",
   700  				MAXBLOCKRANGE, fi.Blockfrom, to))
   701  		}
   702  	}
   703  	return nil
   704  }
   705  
   706  func (fi *FilterInfo) GetExArgFilter() ([]ArgFilter, error) {
   707  	if len(fi.ArgFilter) == 0 {
   708  		return nil, nil
   709  	}
   710  
   711  	var argMap map[string]interface{}
   712  	err := json.Unmarshal(fi.ArgFilter, &argMap)
   713  	if err != nil {
   714  		return nil, errors.New("invalid json format:" + err.Error())
   715  	}
   716  
   717  	argFilter := make([]ArgFilter, len(argMap))
   718  	i := 0
   719  	for key, value := range argMap {
   720  		idx, err := strconv.ParseInt(key, 10, 32)
   721  		if err != nil || idx < 0 {
   722  			return nil, errors.New("invalid argument number:" + key)
   723  		}
   724  		argFilter[i].argNo = int(idx)
   725  		argFilter[i].value = value
   726  		i++
   727  	}
   728  	if i > 0 {
   729  		return argFilter[:i], nil
   730  	}
   731  	return nil, nil
   732  }