github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/common/fsnparams.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/FusionFoundation/efsn/rlp"
     8  )
     9  
    10  /////////////////// param type ///////////////////////
    11  // FSNCallParam wacom
    12  type FSNCallParam struct {
    13  	Func FSNCallFunc
    14  	Data []byte
    15  }
    16  
    17  // GenAssetParam wacom
    18  type GenAssetParam struct {
    19  	Name        string
    20  	Symbol      string
    21  	Decimals    uint8
    22  	Total       *big.Int `json:",string"`
    23  	CanChange   bool
    24  	Description string
    25  }
    26  
    27  // BuyTicketParam wacom
    28  type BuyTicketParam struct {
    29  	Start uint64
    30  	End   uint64
    31  }
    32  
    33  // SendAssetParam wacom
    34  type SendAssetParam struct {
    35  	AssetID Hash
    36  	To      Address
    37  	Value   *big.Int `json:",string"`
    38  }
    39  
    40  // AssetValueChangeExParam wacom
    41  type AssetValueChangeExParam struct {
    42  	AssetID     Hash
    43  	To          Address
    44  	Value       *big.Int `json:",string"`
    45  	IsInc       bool
    46  	TransacData string
    47  }
    48  
    49  // TimeLockParam wacom
    50  type TimeLockParam struct {
    51  	Type      TimeLockType
    52  	AssetID   Hash
    53  	To        Address
    54  	StartTime uint64
    55  	EndTime   uint64
    56  	Value     *big.Int `json:",string"`
    57  }
    58  
    59  // MakeSwapParam wacom
    60  type MakeSwapParam struct {
    61  	FromAssetID   Hash
    62  	FromStartTime uint64
    63  	FromEndTime   uint64
    64  	MinFromAmount *big.Int `json:",string"`
    65  	ToAssetID     Hash
    66  	ToStartTime   uint64
    67  	ToEndTime     uint64
    68  	MinToAmount   *big.Int `json:",string"`
    69  	SwapSize      *big.Int `json:",string"`
    70  	Targes        []Address
    71  	Time          *big.Int
    72  	Description   string
    73  }
    74  
    75  // MakeMultiSwapParam wacom
    76  type MakeMultiSwapParam struct {
    77  	FromAssetID   []Hash
    78  	FromStartTime []uint64
    79  	FromEndTime   []uint64
    80  	MinFromAmount []*big.Int `json:",string"`
    81  	ToAssetID     []Hash
    82  	ToStartTime   []uint64
    83  	ToEndTime     []uint64
    84  	MinToAmount   []*big.Int `json:",string"`
    85  	SwapSize      *big.Int   `json:",string"`
    86  	Targes        []Address
    87  	Time          *big.Int
    88  	Description   string
    89  }
    90  
    91  // RecallSwapParam wacom
    92  type RecallSwapParam struct {
    93  	SwapID Hash
    94  }
    95  
    96  // RecallMultiSwapParam wacom
    97  type RecallMultiSwapParam struct {
    98  	SwapID Hash
    99  }
   100  
   101  // TakeSwapParam wacom
   102  type TakeSwapParam struct {
   103  	SwapID Hash
   104  	Size   *big.Int `json:",string"`
   105  }
   106  
   107  // TakeMultiSwapParam wacom
   108  type TakeMultiSwapParam struct {
   109  	SwapID Hash
   110  	Size   *big.Int `json:",string"`
   111  }
   112  
   113  /////////////////// param ToBytes ///////////////////////
   114  // ToBytes wacom
   115  func (p *FSNCallParam) ToBytes() ([]byte, error) {
   116  	return rlp.EncodeToBytes(p)
   117  }
   118  
   119  // ToBytes wacom
   120  func (p *GenAssetParam) ToBytes() ([]byte, error) {
   121  	return rlp.EncodeToBytes(p)
   122  }
   123  
   124  // ToBytes wacom
   125  func (p *SendAssetParam) ToBytes() ([]byte, error) {
   126  	return rlp.EncodeToBytes(p)
   127  }
   128  
   129  // ToBytes wacom
   130  func (p *TimeLockParam) ToBytes() ([]byte, error) {
   131  	return rlp.EncodeToBytes(p)
   132  }
   133  
   134  // ToBytes wacom
   135  func (p *BuyTicketParam) ToBytes() ([]byte, error) {
   136  	return rlp.EncodeToBytes(p)
   137  }
   138  
   139  // ToBytes wacom
   140  func (p *AssetValueChangeExParam) ToBytes() ([]byte, error) {
   141  	return rlp.EncodeToBytes(p)
   142  }
   143  
   144  // ToBytes wacom
   145  func (p *MakeSwapParam) ToBytes() ([]byte, error) {
   146  	return rlp.EncodeToBytes(p)
   147  }
   148  
   149  // ToBytes wacom
   150  func (p *RecallSwapParam) ToBytes() ([]byte, error) {
   151  	return rlp.EncodeToBytes(p)
   152  }
   153  
   154  // ToBytes wacom
   155  func (p *TakeSwapParam) ToBytes() ([]byte, error) {
   156  	return rlp.EncodeToBytes(p)
   157  }
   158  
   159  // ToBytes wacom
   160  func (p *MakeMultiSwapParam) ToBytes() ([]byte, error) {
   161  	return rlp.EncodeToBytes(p)
   162  }
   163  
   164  // ToBytes wacom
   165  func (p *RecallMultiSwapParam) ToBytes() ([]byte, error) {
   166  	return rlp.EncodeToBytes(p)
   167  }
   168  
   169  // ToBytes wacom
   170  func (p *TakeMultiSwapParam) ToBytes() ([]byte, error) {
   171  	return rlp.EncodeToBytes(p)
   172  }
   173  
   174  type EmptyParam struct{}
   175  
   176  func (p *EmptyParam) ToBytes() ([]byte, error) {
   177  	return nil, nil
   178  }
   179  
   180  func DecodeFsnCallParam(fsnCall *FSNCallParam, funcParam interface{}) (interface{}, error) {
   181  	if len(fsnCall.Data) != 0 {
   182  		err := rlp.DecodeBytes(fsnCall.Data, funcParam)
   183  		if err != nil {
   184  			return nil, fmt.Errorf("decode FSNCallParam err %v", err)
   185  		}
   186  	}
   187  	decodedParam := &struct {
   188  		FuncType  string
   189  		FuncParam interface{}
   190  	}{
   191  		FuncType:  fsnCall.Func.Name(),
   192  		FuncParam: funcParam,
   193  	}
   194  	return decodedParam, nil
   195  }
   196  
   197  func DecodeTxInput(input []byte) (interface{}, error) {
   198  	var fsnCall FSNCallParam
   199  	err := rlp.DecodeBytes(input, &fsnCall)
   200  	if err != nil {
   201  		return nil, fmt.Errorf("decode to FSNCallParam err %v", err)
   202  	}
   203  
   204  	switch fsnCall.Func {
   205  	case GenNotationFunc:
   206  		return DecodeFsnCallParam(&fsnCall, &EmptyParam{})
   207  	case GenAssetFunc:
   208  		return DecodeFsnCallParam(&fsnCall, &GenAssetParam{})
   209  	case SendAssetFunc:
   210  		return DecodeFsnCallParam(&fsnCall, &SendAssetParam{})
   211  	case TimeLockFunc:
   212  		return DecodeFsnCallParam(&fsnCall, &TimeLockParam{})
   213  	case BuyTicketFunc:
   214  		return DecodeFsnCallParam(&fsnCall, &BuyTicketParam{})
   215  	case AssetValueChangeFunc:
   216  		return DecodeFsnCallParam(&fsnCall, &AssetValueChangeExParam{})
   217  	case EmptyFunc:
   218  	case MakeSwapFunc, MakeSwapFuncExt:
   219  		return DecodeFsnCallParam(&fsnCall, &MakeSwapParam{})
   220  	case RecallSwapFunc:
   221  		return DecodeFsnCallParam(&fsnCall, &RecallSwapParam{})
   222  	case TakeSwapFunc, TakeSwapFuncExt:
   223  		return DecodeFsnCallParam(&fsnCall, &TakeSwapParam{})
   224  	case RecallMultiSwapFunc:
   225  		return DecodeFsnCallParam(&fsnCall, &RecallMultiSwapParam{})
   226  	case MakeMultiSwapFunc:
   227  		return DecodeFsnCallParam(&fsnCall, &MakeMultiSwapParam{})
   228  	case TakeMultiSwapFunc:
   229  		return DecodeFsnCallParam(&fsnCall, &TakeMultiSwapParam{})
   230  	case ReportIllegalFunc:
   231  		return fsnCall, fmt.Errorf("ReportIllegal should processed by datong.DecodeTxInput")
   232  	}
   233  	return nil, fmt.Errorf("Unknown FuncType %v", fsnCall.Func)
   234  }
   235  
   236  /////////////////// param checking ///////////////////////
   237  // Check wacom
   238  func (p *FSNCallParam) Check(blockNumber *big.Int) error {
   239  	return nil
   240  }
   241  
   242  // Check wacom
   243  func (p *GenAssetParam) Check(blockNumber *big.Int) error {
   244  	if len(p.Name) == 0 || len(p.Symbol) == 0 || p.Total == nil || p.Total.Cmp(Big0) < 0 {
   245  		return fmt.Errorf("GenAssetFunc name, symbol and total must be set")
   246  	}
   247  	if p.Decimals > 18 {
   248  		return fmt.Errorf("GenAssetFunc decimals must be between 0 and 18")
   249  	}
   250  	if len(p.Description) > 1024 {
   251  		return fmt.Errorf("GenAsset description length is greater than 1024 chars")
   252  	}
   253  	if len(p.Name) > 128 {
   254  		return fmt.Errorf("GenAsset name length is greater than 128 chars")
   255  	}
   256  	if len(p.Symbol) > 64 {
   257  		return fmt.Errorf("GenAsset symbol length is greater than 64 chars")
   258  
   259  	}
   260  	return nil
   261  }
   262  
   263  // Check wacom
   264  func (p *SendAssetParam) Check(blockNumber *big.Int) error {
   265  	if p.Value == nil || p.Value.Cmp(Big0) <= 0 {
   266  		return fmt.Errorf("Value must be set and greater than 0")
   267  	}
   268  	if p.To == (Address{}) {
   269  		return fmt.Errorf("receiver address must be set and not zero address")
   270  	}
   271  	if p.AssetID == (Hash{}) {
   272  		return fmt.Errorf("empty asset ID, 'asset' must be specified instead of AssetID.")
   273  	}
   274  	return nil
   275  }
   276  
   277  // Check wacom
   278  func (p *TimeLockParam) Check(blockNumber *big.Int, timestamp uint64) error {
   279  
   280  	if p.Value == nil || p.Value.Cmp(Big0) <= 0 {
   281  		return fmt.Errorf("Value must be set and greater than 0")
   282  	}
   283  	if p.StartTime > p.EndTime {
   284  		return fmt.Errorf("StartTime must be less than or equal to EndTime")
   285  	}
   286  	if p.EndTime < timestamp {
   287  		return fmt.Errorf("EndTime must be greater than latest block time")
   288  	}
   289  
   290  	return nil
   291  }
   292  
   293  // Check wacom
   294  func (p *BuyTicketParam) Check(blockNumber *big.Int, timestamp uint64) error {
   295  	start, end := p.Start, p.End
   296  	// check lifetime too short ticket
   297  	if end <= start || end < start+30*24*3600 {
   298  		return fmt.Errorf("BuyTicket end must be greater than start + 1 month")
   299  	}
   300  	if timestamp != 0 {
   301  		// check future ticket
   302  		if start > timestamp+3*3600 {
   303  			return fmt.Errorf("BuyTicket start must be lower than latest block time + 3 hour")
   304  		}
   305  		// check ticket lifetime
   306  		if IsHardFork(2, blockNumber) {
   307  			// use 29 days here to check lifetime, to relax auto buy ticket tx checking in txpool
   308  			if end < timestamp+29*24*3600 {
   309  				return fmt.Errorf("BuyTicket end must be greater than latest block time + 1 month")
   310  			}
   311  		} else {
   312  			if end < timestamp+7*24*3600 {
   313  				return fmt.Errorf("BuyTicket end must be greater than latest block time + 1 week")
   314  			}
   315  		}
   316  	}
   317  	return nil
   318  }
   319  
   320  // Check wacom
   321  func (p *AssetValueChangeExParam) Check(blockNumber *big.Int) error {
   322  	if p.Value == nil || p.Value.Cmp(Big0) <= 0 {
   323  		return fmt.Errorf("Value must be set and greater than 0")
   324  	}
   325  	if len(p.TransacData) > 256 {
   326  		return fmt.Errorf("TransacData must not be greater than 256")
   327  	}
   328  	return nil
   329  }
   330  
   331  // Check wacom
   332  func (p *MakeSwapParam) Check(blockNumber *big.Int, timestamp uint64) error {
   333  	if p.MinFromAmount == nil || p.MinFromAmount.Cmp(Big0) <= 0 ||
   334  		p.MinToAmount == nil || p.MinToAmount.Cmp(Big0) <= 0 ||
   335  		p.SwapSize == nil || p.SwapSize.Cmp(Big0) <= 0 {
   336  		return fmt.Errorf("MinFromAmount,MinToAmount and SwapSize must be ge 1")
   337  	}
   338  	if len(p.Description) > 1024 {
   339  		return fmt.Errorf("MakeSwap description length is greater than 1024 chars")
   340  	}
   341  	total := new(big.Int).Mul(p.MinFromAmount, p.SwapSize)
   342  	if total.Cmp(Big0) <= 0 {
   343  		return fmt.Errorf("size * MinFromAmount too large")
   344  	}
   345  
   346  	toTotal := new(big.Int).Mul(p.MinToAmount, p.SwapSize)
   347  	if toTotal.Cmp(Big0) <= 0 {
   348  		return fmt.Errorf("size * MinToAmount too large")
   349  	}
   350  
   351  	if p.FromStartTime > p.FromEndTime {
   352  		return fmt.Errorf("MakeSwap FromStartTime > FromEndTime")
   353  	}
   354  	if p.ToStartTime > p.ToEndTime {
   355  		return fmt.Errorf("MakeSwap ToStartTime > ToEndTime")
   356  	}
   357  
   358  	if p.FromEndTime <= timestamp {
   359  		return fmt.Errorf("MakeSwap FromEndTime <= latest blockTime")
   360  	}
   361  	if p.ToEndTime <= timestamp {
   362  		return fmt.Errorf("MakeSwap ToEndTime <= latest blockTime")
   363  	}
   364  
   365  	if p.ToAssetID == OwnerUSANAssetID {
   366  		return fmt.Errorf("USAN's cannot be swapped")
   367  	}
   368  
   369  	return nil
   370  }
   371  
   372  // Check wacom
   373  func (p *RecallSwapParam) Check(blockNumber *big.Int, swap *Swap) error {
   374  	return nil
   375  }
   376  
   377  // Check wacom
   378  func (p *TakeSwapParam) Check(blockNumber *big.Int, swap *Swap, timestamp uint64) error {
   379  	if p.Size == nil || p.Size.Cmp(Big0) <= 0 ||
   380  		swap.SwapSize == nil || p.Size.Cmp(swap.SwapSize) > 0 {
   381  
   382  		return fmt.Errorf("Size must be ge 1 and le Swapsize")
   383  	}
   384  
   385  	if swap.FromEndTime <= timestamp {
   386  		return fmt.Errorf("swap expired: FromEndTime <= latest blockTime")
   387  	}
   388  	if swap.ToEndTime <= timestamp {
   389  		return fmt.Errorf("swap expired: ToEndTime <= latest blockTime")
   390  	}
   391  
   392  	return nil
   393  }
   394  
   395  // Check wacom
   396  func (p *MakeMultiSwapParam) Check(blockNumber *big.Int, timestamp uint64) error {
   397  	if p.MinFromAmount == nil || len(p.MinFromAmount) == 0 {
   398  		return fmt.Errorf("MinFromAmount must be specified")
   399  	}
   400  	if p.MinToAmount == nil || len(p.MinToAmount) == 0 {
   401  		return fmt.Errorf("MinToAmount must be specified")
   402  	}
   403  	if p.SwapSize == nil || p.SwapSize.Cmp(Big0) <= 0 {
   404  		return fmt.Errorf("SwapSize must be ge 1")
   405  	}
   406  
   407  	if len(p.MinFromAmount) != len(p.FromEndTime) ||
   408  		len(p.MinFromAmount) != len(p.FromAssetID) ||
   409  		len(p.MinFromAmount) != len(p.FromStartTime) {
   410  		return fmt.Errorf("MinFromAmount FromEndTime and FromStartTime array length must be same size")
   411  	}
   412  	if len(p.MinToAmount) != len(p.ToEndTime) ||
   413  		len(p.MinToAmount) != len(p.ToAssetID) ||
   414  		len(p.MinToAmount) != len(p.ToStartTime) {
   415  		return fmt.Errorf("MinToAmount ToEndTime and ToStartTime array length must be same size")
   416  	}
   417  
   418  	ln := len(p.MinFromAmount)
   419  	for i := 0; i < ln; i++ {
   420  		if p.MinFromAmount[i] == nil || p.MinFromAmount[i].Cmp(Big0) <= 0 {
   421  			return fmt.Errorf("MinFromAmounts must be ge 1")
   422  		}
   423  		total := new(big.Int).Mul(p.MinFromAmount[i], p.SwapSize)
   424  		if total.Cmp(Big0) <= 0 {
   425  			return fmt.Errorf("size * MinFromAmount too large")
   426  		}
   427  		if p.FromStartTime[i] > p.FromEndTime[i] {
   428  			return fmt.Errorf("MakeMultiSwap FromStartTime > FromEndTime")
   429  		}
   430  		if p.FromEndTime[i] <= timestamp {
   431  			return fmt.Errorf("MakeMultiSwap FromEndTime <= latest blockTime")
   432  		}
   433  	}
   434  
   435  	ln = len(p.MinToAmount)
   436  	for i := 0; i < ln; i++ {
   437  		if p.MinToAmount[i] == nil || p.MinToAmount[i].Cmp(Big0) <= 0 {
   438  			return fmt.Errorf("MinToAmounts must be ge 1")
   439  		}
   440  		toTotal := new(big.Int).Mul(p.MinToAmount[i], p.SwapSize)
   441  		if toTotal.Cmp(Big0) <= 0 {
   442  			return fmt.Errorf("size * MinToAmount too large")
   443  		}
   444  		if p.ToStartTime[i] > p.ToEndTime[i] {
   445  			return fmt.Errorf("MakeMultiSwap ToStartTime > ToEndTime")
   446  		}
   447  		if p.ToEndTime[i] <= timestamp {
   448  			return fmt.Errorf("MakeMultiSwap ToEndTime <= latest blockTime")
   449  		}
   450  	}
   451  
   452  	if len(p.Description) > 1024 {
   453  		return fmt.Errorf("MakeSwap description length is greater than 1024 chars")
   454  	}
   455  
   456  	for _, toAssetID := range p.ToAssetID {
   457  		if toAssetID == OwnerUSANAssetID {
   458  			return fmt.Errorf("USAN's cannot be multi swapped")
   459  		}
   460  	}
   461  	for _, fromAssetID := range p.FromAssetID {
   462  		if fromAssetID == OwnerUSANAssetID {
   463  			return fmt.Errorf("USAN's cannot be multi swapped")
   464  		}
   465  	}
   466  	return nil
   467  }
   468  
   469  // Check wacom
   470  func (p *RecallMultiSwapParam) Check(blockNumber *big.Int, swap *MultiSwap) error {
   471  	return nil
   472  }
   473  
   474  // Check wacom
   475  func (p *TakeMultiSwapParam) Check(blockNumber *big.Int, swap *MultiSwap, timestamp uint64) error {
   476  	if p.Size == nil || p.Size.Cmp(Big0) <= 0 ||
   477  		swap.SwapSize == nil || p.Size.Cmp(swap.SwapSize) > 0 {
   478  
   479  		return fmt.Errorf("Size must be ge 1 and le Swapsize")
   480  	}
   481  
   482  	ln := len(swap.FromEndTime)
   483  	for i := 0; i < ln; i++ {
   484  		if swap.FromEndTime[i] <= timestamp {
   485  			return fmt.Errorf("swap expired: FromEndTime <= latest blockTime")
   486  		}
   487  	}
   488  
   489  	ln = len(swap.ToEndTime)
   490  	for i := 0; i < ln; i++ {
   491  		if swap.ToEndTime[i] <= timestamp {
   492  			return fmt.Errorf("swap expired: ToEndTime <= latest blockTime")
   493  		}
   494  	}
   495  	return nil
   496  }