<commit_before>package asset

import (
	"context"
	"encoding/binary"
	"encoding/json"
	"sync"

	"github.com/golang/groupcache/lru"
	"github.com/golang/groupcache/singleflight"
	dbm "github.com/tendermint/tmlibs/db"
	"golang.org/x/crypto/sha3"

	"github.com/bytom/blockchain/signers"
	cfg "github.com/bytom/config"
	"github.com/bytom/consensus"
	"github.com/bytom/crypto/ed25519"
	"github.com/bytom/crypto/ed25519/chainkd"
	chainjson "github.com/bytom/encoding/json"
	"github.com/bytom/errors"
	"github.com/bytom/protocol"
	"github.com/bytom/protocol/bc"
	"github.com/bytom/protocol/vm/vmutil"
)

func init() {
	DefaultNativeAsset = generateNativeAsset()
}

var DefaultNativeAsset *Asset

const (
	maxAssetCache = 1000
	assetPrefix   = "ASS:"
	//AliasPrefix is asset alias prefix
	AliasPrefix = "ALS:"
	//ExternalAssetPrefix is external definition assets prefix
	ExternalAssetPrefix = "EXA"
	indexPrefix   = "ASSIDX:"
)

func generateNativeAsset() *Asset {
	genesisBlock := cfg.GenerateGenesisBlock()
	signer := &signers.Signer{Type: "internal"}
	alias := consensus.BTMAlias

	definitionBytes, _ := serializeAssetDef(consensus.BTMDefinitionMap)

	return &Asset{
		Signer:            signer,
		AssetID:           *consensus.BTMAssetID,
		Alias:             &alias,
		VMVersion:         1,
		DefinitionMap:     consensus.BTMDefinitionMap,
		RawDefinitionByte: definitionBytes,
		InitialBlockHash:  genesisBlock.Hash()}
}

func AliasKey(name string) []byte {
	return []byte(AliasPrefix + name)
}

//Key asset store prefix
func Key(id *bc.AssetID) []byte {
	name := id.String()
	return []byte(assetPrefix + name)
}

func indexKey(xpub chainkd.XPub) []byte {
	return []byte(indexPrefix + xpub.String())
}

//CalcExtAssetKey return store external assets key
func CalcExtAssetKey(id *bc.AssetID) []byte {
	name := id.String()
	return []byte(ExternalAssetPrefix + name)
}

// pre-define errors for supporting bytom errorFormatter
var (
	ErrDuplicateAlias = errors.New("duplicate asset alias")
	ErrDuplicateAsset = errors.New("duplicate asset id")
	ErrSerializing    = errors.New("serializing asset definition")
	ErrMarshalAsset   = errors.New("failed marshal asset")
	ErrFindAsset      = errors.New("fail to find asset")
	ErrInternalAsset  = errors.New("btm has been defined as the internal asset")
	ErrNullAlias      = errors.New("null asset alias")
)

//NewRegistry create new registry
func NewRegistry(db dbm.DB, chain *protocol.Chain) *Registry {
	return &Registry{
		db:               db,
		chain:            chain,
		initialBlockHash: chain.InitialBlockHash,
		cache:            lru.New(maxAssetCache),
		aliasCache:       lru.New(maxAssetCache),
	}
}

// Registry tracks and stores all known assets on a blockchain.
type Registry struct {
	db               dbm.DB
	chain            *protocol.Chain
	initialBlockHash bc.Hash

	idGroup    singleflight.Group
	aliasGroup singleflight.Group

	cacheMu    sync.Mutex
	cache      *lru.Cache
	aliasCache *lru.Cache

	assetIndexMu sync.Mutex<commit_msg>Don't init native asset in init function (#324)<commit_after>package asset

import (
	"context"
	"encoding/binary"
	"encoding/json"
	"sync"

	"github.com/golang/groupcache/lru"
	"github.com/golang/groupcache/singleflight"
	dbm "github.com/tendermint/tmlibs/db"
	"golang.org/x/crypto/sha3"

	"github.com/bytom/blockchain/signers"
	cfg "github.com/bytom/config"
	"github.com/bytom/consensus"
	"github.com/bytom/crypto/ed25519"
	"github.com/bytom/crypto/ed25519/chainkd"
	chainjson "github.com/bytom/encoding/json"
	"github.com/bytom/errors"
	"github.com/bytom/protocol"
	"github.com/bytom/protocol/bc"
	"github.com/bytom/protocol/vm/vmutil"
)

var DefaultNativeAsset *Asset

const (
	maxAssetCache = 1000
	assetPrefix   = "ASS:"
	//AliasPrefix is asset alias prefix
	AliasPrefix = "ALS:"
	//ExternalAssetPrefix is external definition assets prefix
	ExternalAssetPrefix = "EXA"
	indexPrefix         = "ASSIDX:"
)

func initNativeAsset() {
	genesisBlock := cfg.GenerateGenesisBlock()
	signer := &signers.Signer{Type: "internal"}
	alias := consensus.BTMAlias

	definitionBytes, _ := serializeAssetDef(consensus.BTMDefinitionMap)
	DefaultNativeAsset = &Asset{
		Signer:            signer,
		AssetID:           *consensus.BTMAssetID,
		Alias:             &alias,
		VMVersion:         1,
		DefinitionMap:     consensus.BTMDefinitionMap,
		RawDefinitionByte: definitionBytes,
		InitialBlockHash:  genesisBlock.Hash(),
	}
}

func AliasKey(name string) []byte {
	return []byte(AliasPrefix + name)
}

//Key asset store prefix
func Key(id *bc.AssetID) []byte {
	name := id.String()
	return []byte(assetPrefix + name)
}

func indexKey(xpub chainkd.XPub) []byte {
	return []byte(indexPrefix + xpub.String())
}

//CalcExtAssetKey return store external assets key
func CalcExtAssetKey(id *bc.AssetID) []byte {
	name := id.String()
	return []byte(ExternalAssetPrefix + name)
}

// pre-define errors for supporting bytom errorFormatter
var (
	ErrDuplicateAlias = errors.New("duplicate asset alias")
	ErrDuplicateAsset = errors.New("duplicate asset id")
	ErrSerializing    = errors.New("serializing asset definition")
	ErrMarshalAsset   = errors.New("failed marshal asset")
	ErrFindAsset      = errors.New("fail to find asset")
	ErrInternalAsset  = errors.New("btm has been defined as the internal asset")
	ErrNullAlias      = errors.New("null asset alias")
)

//NewRegistry create new registry
func NewRegistry(db dbm.DB, chain *protocol.Chain) *Registry {
	initNativeAsset()
	return &Registry{
		db:               db,
		chain:            chain,
		initialBlockHash: chain.InitialBlockHash,
		cache:            lru.New(maxAssetCache),
		aliasCache:       lru.New(maxAssetCache),
	}
}

// Registry tracks and stores all known assets on a blockchain.
type Registry struct {
	db               dbm.DB
	chain            *protocol.Chain
	initialBlockHash bc.Hash

	idGroup    singleflight.Group
	aliasGroup singleflight.Group

	cacheMu    sync.Mutex
	cache      *lru.Cache
	aliasCache *lru.Cache

	assetIndexMu sync.Mutex
{'fraction_non_alphanumeric': 0.11291130783363955, 'fraction_numerical': 0.0058459996659428765, 'mean_word_length': 3.8603896103896105, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6579917', 'n_tokens_mistral': 2052, 'n_tokens_neox': 1966, 'n_words': 436}