Files
3a9331169b Update avalanchego to v1.9.0-fuji (#472)
Co-authored-by: dhrubabasu <[email protected]>
Co-authored-by: Patrick O'Grady <[email protected]>
Co-authored-by: Stephen <[email protected]>
2022-10-02 20:20:49 -04:00

649 lines
14 KiB
Go

// (c) 2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package params
import (
"math/big"
"net/url"
"strconv"
"strings"
"time"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/ortelius/db"
"github.com/ava-labs/ortelius/models"
"github.com/gocraft/dbr/v2"
)
const (
TransactionSortTimestampAsc TransactionSort = iota
TransactionSortTimestampDesc
TransactionSortDefault = TransactionSortTimestampAsc
TransactionSortTimestampAscStr = "timestamp-asc"
TransactionSortTimestampDescStr = "timestamp-desc"
)
var (
_ Param = &SearchParams{}
_ Param = &AggregateParams{}
_ Param = &ListTransactionsParams{}
_ Param = &ListAssetsParams{}
_ Param = &ListAddressesParams{}
_ Param = &ListOutputsParams{}
)
type SearchParams struct {
ListParams ListParams
}
func (p *SearchParams) ForValues(v uint8, q url.Values) error {
return p.ListParams.ForValues(v, q)
}
func (p *SearchParams) CacheKey() []string {
return p.ListParams.CacheKey()
}
type TxfeeAggregateParams struct {
ListParams ListParams
IntervalSize time.Duration
ChainIDs []string
}
func (p *TxfeeAggregateParams) ForValues(version uint8, q url.Values) (err error) {
err = p.ListParams.ForValues(version, q)
if err != nil {
return err
}
p.ChainIDs = q[KeyChainID]
p.IntervalSize, err = GetQueryInterval(q, KeyIntervalSize)
if err != nil {
return err
}
return nil
}
func (p *TxfeeAggregateParams) CacheKey() []string {
k := make([]string, 0, 4)
k = append(k,
CacheKey(KeyIntervalSize, int64(p.IntervalSize.Seconds())),
CacheKey(KeyChainID, strings.Join(p.ChainIDs, "|")),
)
return append(p.ListParams.CacheKey(), k...)
}
func (p *TxfeeAggregateParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
return b
}
type AggregateParams struct {
ListParams ListParams
ChainIDs []string
AssetID *ids.ID
IntervalSize time.Duration
}
func (p *AggregateParams) ForValues(version uint8, q url.Values) (err error) {
err = p.ListParams.ForValues(version, q)
if err != nil {
return err
}
p.ChainIDs = q[KeyChainID]
p.AssetID, err = GetQueryID(q, KeyAssetID)
if err != nil {
return err
}
p.IntervalSize, err = GetQueryInterval(q, KeyIntervalSize)
if err != nil {
return err
}
return nil
}
func (p *AggregateParams) CacheKey() []string {
k := make([]string, 0, 4)
if p.AssetID != nil {
k = append(k, CacheKey(KeyAssetID, p.AssetID.String()))
}
k = append(k,
CacheKey(KeyIntervalSize, int64(p.IntervalSize.Seconds())),
CacheKey(KeyChainID, strings.Join(p.ChainIDs, "|")),
)
return append(p.ListParams.CacheKey(), k...)
}
func (p *AggregateParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
b.Where("avm_outputs.created_at >= ?", p.ListParams.StartTime)
b.Where("avm_outputs.created_at < ?", p.ListParams.EndTime)
if p.AssetID != nil {
b.Where("avm_outputs.asset_id = ?", p.AssetID.String())
}
if len(p.ChainIDs) > 0 {
b.Where("avm_outputs.chain_id = ?", p.ChainIDs)
}
return b
}
type ListTransactionsParams struct {
ListParams ListParams
ChainIDs []string
Addresses []ids.ShortID
AssetID *ids.ID
OutputOutputTypes []uint64
OutputGroupIDs []uint64
DisableGenesis bool
Sort TransactionSort
}
func (p *ListTransactionsParams) ForValues(v uint8, q url.Values) error {
err := p.ListParams.ForValuesAllowOffset(v, q)
if err != nil {
return err
}
p.Sort = TransactionSortDefault
sortBys, ok := q[KeySortBy]
if ok && len(sortBys) >= 1 {
p.Sort = toTransactionSort(sortBys[0])
}
p.ChainIDs = q[KeyChainID]
p.AssetID, err = GetQueryID(q, KeyAssetID)
if err != nil {
return err
}
outputOutputTypes := q[KeyOutputOutputType]
for _, outputOutputType := range outputOutputTypes {
outpuOutputTypeValue, err := strconv.ParseUint(outputOutputType, 10, 32)
if err != nil {
return err
}
p.OutputOutputTypes = append(p.OutputOutputTypes, outpuOutputTypeValue)
}
outputGroupIDs := q[KeyOutputGroupID]
for _, outputGroupID := range outputGroupIDs {
outputGroupIDValue, err := strconv.ParseUint(outputGroupID, 10, 64)
if err != nil {
return err
}
p.OutputGroupIDs = append(p.OutputGroupIDs, outputGroupIDValue)
}
addressStrs := q[KeyAddress]
for _, addressStr := range addressStrs {
addr, err := AddressFromString(addressStr)
if err != nil {
return err
}
p.Addresses = append(p.Addresses, addr)
}
p.DisableGenesis, err = GetQueryBool(q, KeyDisableGenesis, false)
if err != nil {
return err
}
return nil
}
func (p *ListTransactionsParams) CacheKey() []string {
k := p.ListParams.CacheKey()
k = append(k, CacheKey(KeySortBy, p.Sort))
if p.AssetID != nil {
k = append(k, CacheKey(KeyAssetID, p.AssetID.String()))
}
for _, address := range p.Addresses {
k = append(k, CacheKey(KeyAddress, address.String()))
}
k = append(k,
CacheKey(KeyChainID, strings.Join(p.ChainIDs, "|")),
CacheKey(KeyDisableGenesis, p.DisableGenesis),
)
return k
}
func (p *ListTransactionsParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
return nil
}
type ListCTransactionsParams struct {
ListParams ListParams
CAddresses []string
CAddressesTo []string
CAddressesFrom []string
Hashes []string
Sort TransactionSort
BlockStart *big.Int
BlockEnd *big.Int
}
func (p *ListCTransactionsParams) ForValues(v uint8, q url.Values) error {
err := p.ListParams.ForValues(v, q)
if err != nil {
return err
}
p.Sort = TransactionSortDefault
sortBys, ok := q[KeySortBy]
if ok && len(sortBys) >= 1 {
p.Sort = toTransactionSort(sortBys[0])
}
addressStrs := q[KeyAddress]
for _, addressStr := range addressStrs {
if !strings.HasPrefix(addressStr, "0x") {
addressStr = "0x" + addressStr
}
p.CAddresses = append(p.CAddresses, strings.ToLower(addressStr))
}
addressStrs = q[KeyToAddress]
for _, addressStr := range addressStrs {
if !strings.HasPrefix(addressStr, "0x") {
addressStr = "0x" + addressStr
}
p.CAddressesTo = append(p.CAddressesTo, strings.ToLower(addressStr))
}
addressStrs = q[KeyFromAddress]
for _, addressStr := range addressStrs {
if !strings.HasPrefix(addressStr, "0x") {
addressStr = "0x" + addressStr
}
p.CAddressesFrom = append(p.CAddressesFrom, strings.ToLower(addressStr))
}
blockStartStrs := q[KeyBlockStart]
for _, blockStartStr := range blockStartStrs {
nint := big.NewInt(0)
if _, ok := nint.SetString(blockStartStr, 10); ok {
p.BlockStart = nint
}
}
blockEndStrs := q[KeyBlockEnd]
for _, blockEndStr := range blockEndStrs {
nint := big.NewInt(0)
if _, ok := nint.SetString(blockEndStr, 10); ok {
p.BlockEnd = nint
}
}
hashStrs := q[KeyHash]
for _, hashStr := range hashStrs {
if !strings.HasPrefix(hashStr, "0x") {
hashStr = "0x" + hashStr
}
p.Hashes = append(p.Hashes, hashStr)
}
return nil
}
func (p *ListCTransactionsParams) CacheKey() []string {
k := p.ListParams.CacheKey()
k = append(k, CacheKey(KeySortBy, p.Sort))
for _, address := range p.CAddresses {
k = append(k, CacheKey(KeyAddress, address))
}
return k
}
func (p *ListCTransactionsParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
p.ListParams.ApplyPk(db.TableCvmTransactionsTxdata, b, "hash", false)
return b
}
type ListAssetsParams struct {
ListParams ListParams
Alias string
PathParamID string
}
func (p *ListAssetsParams) ForValues(v uint8, q url.Values) error {
if err := p.ListParams.ForValues(v, q); err != nil {
return err
}
p.Alias = GetQueryString(q, KeyAlias, "")
return nil
}
func (p *ListAssetsParams) CacheKey() []string {
return append(p.ListParams.CacheKey(),
CacheKey(KeyAlias, p.Alias),
CacheKey("PathParamID", p.PathParamID))
}
func (p *ListAssetsParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
// we don't want to apply the query on the primary key.
// clear out the Query for the Apply call.
querySave := p.ListParams.Query
p.ListParams.Query = ""
p.ListParams.Apply("avm_assets", b)
p.ListParams.Query = querySave
if p.ListParams.Query != "" {
b.Where(dbr.Or(
dbr.Like("avm_assets.alias", p.ListParams.Query+"%"),
dbr.Like("avm_assets.name", p.ListParams.Query+"%"),
dbr.Like("avm_assets.symbol", p.ListParams.Query+"%"),
))
}
if p.Alias != "" {
b.Where("avm_assets.alias = ?", p.Alias)
}
return b
}
type ListAddressesParams struct {
ListParams ListParams
ChainIDs []string
Address *ids.ShortID
}
func (p *ListAddressesParams) ForValues(v uint8, q url.Values) error {
if err := p.ListParams.ForValues(v, q); err != nil {
return err
}
p.ChainIDs = q[KeyChainID]
var err error
if p.Address, err = GetQueryAddress(q, KeyAddress); err != nil {
return err
}
if p.Address == nil && p.ListParams.Query != "" {
addr, err := AddressFromString(p.ListParams.Query)
if err != nil {
return err
}
p.Address = &addr
}
return nil
}
func (p *ListAddressesParams) CacheKey() []string {
k := p.ListParams.CacheKey()
if p.Address != nil {
k = append(k, CacheKey(KeyAddress, p.Address.String()))
}
k = append(k, CacheKey(KeyChainID, strings.Join(p.ChainIDs, "|")))
return k
}
func (p *ListAddressesParams) Apply(b *dbr.SelectBuilder, accumulateReader bool) *dbr.SelectBuilder {
if !accumulateReader {
b = p.ListParams.ApplyPk("avm_output_addresses", b, "output_id", false)
if len(p.ChainIDs) != 0 {
b.Where("avm_outputs.chain_id IN ?", p.ChainIDs)
}
if p.Address != nil {
b.Where("avm_output_addresses.address = ?", p.Address.String())
}
} else {
b = p.ListParams.ApplyPk("avm_output_addresses", b, "output_id", true)
if len(p.ChainIDs) != 0 {
b.Where("accumulate_balances_received.chain_id IN ?", p.ChainIDs)
}
if p.Address != nil {
b.Where("accumulate_balances_received.address = ?", p.Address.String())
}
}
return b
}
type AddressChainsParams struct {
ListParams ListParams
Addresses []ids.ShortID
}
func (p *AddressChainsParams) ForValues(v uint8, q url.Values) error {
if err := p.ListParams.ForValues(v, q); err != nil {
return err
}
addressStrs := q[KeyAddress]
for _, addressStr := range addressStrs {
addr, err := AddressFromString(addressStr)
if err != nil {
return err
}
p.Addresses = append(p.Addresses, addr)
}
return nil
}
func (p *AddressChainsParams) CacheKey() []string {
k := p.ListParams.CacheKey()
for _, address := range p.Addresses {
k = append(k, CacheKey(KeyAddress, address.String()))
}
return k
}
func (p *AddressChainsParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
p.ListParams.Apply("address_chain", b)
if len(p.Addresses) == 0 {
return b
}
addrs := make([]string, len(p.Addresses))
for i, id := range p.Addresses {
addrs[i] = id.String()
}
return b.Where("address_chain.address IN ?", addrs)
}
type ListOutputsParams struct {
ListParams ListParams
ChainIDs []string
Addresses []ids.ShortID
Spent *bool
}
func (p *ListOutputsParams) ForValues(v uint8, q url.Values) error {
if err := p.ListParams.ForValues(v, q); err != nil {
return err
}
p.ChainIDs = q[KeyChainID]
addressStrs := q[KeyAddress]
for _, addressStr := range addressStrs {
addr, err := AddressFromString(addressStr)
if err != nil {
return err
}
p.Addresses = append(p.Addresses, addr)
}
spentStrs, ok := q[KeySpent]
if ok || len(spentStrs) >= 1 {
b, err := strconv.ParseBool(spentStrs[0])
if err != nil {
return err
}
p.Spent = &b
}
return nil
}
func (p *ListOutputsParams) CacheKey() []string {
k := append(p.ListParams.CacheKey(),
CacheKey(KeyChainID, strings.Join(p.ChainIDs, "|")))
for _, address := range p.Addresses {
k = append(k, CacheKey(KeyAddress, address.String()))
}
if p.Spent != nil {
k = append(k, CacheKey(KeySpent, *p.Spent))
}
return k
}
func (p *ListOutputsParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
p.ListParams.Apply("avm_outputs", b)
if p.Spent != nil {
if *p.Spent {
b.Where("avm_outputs_redeeming.redeeming_transaction_id IS NOT NULL")
} else {
b.Where("avm_outputs_redeeming.redeeming_transaction_id IS NULL")
}
}
if p.Addresses != nil {
addrStrs := make([]string, len(p.Addresses))
for i, addr := range p.Addresses {
addrStrs[i] = addr.String()
}
b.LeftJoin("avm_output_addresses", "avm_outputs.id = avm_output_addresses.output_id").
Where("avm_output_addresses.address IN ?", addrStrs)
}
if len(p.ChainIDs) > 0 {
b.Where("avm_outputs.chain_id = ?", p.ChainIDs)
}
if p.ListParams.StartTimeProvided && !p.ListParams.StartTime.IsZero() {
b.Where("avm_outputs.created_at >= ?", p.ListParams.StartTime)
}
if p.ListParams.EndTimeProvided && !p.ListParams.EndTime.IsZero() {
b.Where("avm_outputs.created_at < ?", p.ListParams.EndTime)
}
return b
}
type ListBlocksParams struct {
ListParams ListParams
Types []models.BlockType
Sort BlockSort
}
func (p *ListBlocksParams) ForValues(v uint8, q url.Values) error {
return p.ListParams.ForValues(v, q)
}
func (p *ListBlocksParams) CacheKey() []string {
return p.ListParams.CacheKey()
}
func (p *ListBlocksParams) Apply(b *dbr.SelectBuilder) *dbr.SelectBuilder {
return p.ListParams.Apply("pvm_blocks", b)
}
func ForValueChainID(chainID *ids.ID, chainIDs []string) []string {
if chainID == nil {
return chainIDs
}
if chainIDs == nil {
chainIDs = make([]string, 0, 1)
}
cnew := chainID.String()
var found bool
for _, cval := range chainIDs {
if cval == cnew {
found = true
break
}
}
if found {
return chainIDs
}
chainIDs = append([]string{cnew}, chainIDs...)
return chainIDs
}
// Sorting
type TransactionSort uint8
func toTransactionSort(s string) TransactionSort {
switch s {
case TransactionSortTimestampAscStr:
return TransactionSortTimestampAsc
case TransactionSortTimestampDescStr:
return TransactionSortTimestampDesc
}
return TransactionSortDefault
}
func (t TransactionSort) String() string {
if t == TransactionSortTimestampDesc {
return TransactionSortTimestampDescStr
}
return TransactionSortTimestampAscStr
}
type BlockSort string
type TxDataParam struct {
ListParams ListParams
ID string
}
func (p *TxDataParam) ForValues(v uint8, q url.Values) error {
if err := p.ListParams.ForValues(v, q); err != nil {
return err
}
return nil
}
func (p *TxDataParam) CacheKey() []string {
return p.ListParams.CacheKey()
}