diff --git a/api/types.go b/api/types.go index 45f77c05..0981584e 100644 --- a/api/types.go +++ b/api/types.go @@ -96,7 +96,6 @@ type Vout struct { // Contains SyscoinSpecific asset information hex decoded and pertinent to API display type AssetSpecific struct { AssetGuid uint32 `json:"assetGuid"` - AddrStr string `json:"addrStr,omitempty"` Contract string `json:"contract,omitempty"` Symbol string `json:"symbol"` PubData map[string]interface{} `json:"pubData"` @@ -115,7 +114,6 @@ type AssetSpecific struct { // Contains SyscoinSpecific assets information when searching for assets type AssetsSpecific struct { AssetGuid uint32 `json:"assetGuid"` - AddrStr string `json:"addrStr,omitempty"` Contract string `json:"contract"` Symbol string `json:"symbol"` PubData map[string]interface{} `json:"pubData"` diff --git a/api/worker.go b/api/worker.go index ddb73581..74419d0f 100644 --- a/api/worker.go +++ b/api/worker.go @@ -1097,34 +1097,11 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco } if ba.AssetBalances != nil && option > AccountDetailsBasic { tokens = make(bchain.Tokens, 0, len(ba.AssetBalances)+1) - var ownerFound bool = false for k, v := range ba.AssetBalances { dbAsset, errAsset := w.db.GetAsset(uint32(k), nil) if errAsset != nil || dbAsset == nil { return nil, errAsset } - if !ownerFound { - // add token as unallocated if address matches asset owner address - if bytes.Equal(addrDesc, dbAsset.AddrDesc) { - ownerBalance := big.NewInt(dbAsset.AssetObj.Balance) - totalOwnerAssetReceived := bchain.ReceivedSatFromBalances(ownerBalance, v.SentSat) - assetGuid := strconv.FormatUint(uint64(k), 10) - tokens = append(tokens, &bchain.Token{ - Type: bchain.SPTUnallocatedTokenType, - AddrStr: dbAsset.AddrDesc.String(), - Name: assetGuid + " (" + dbAsset.AssetObj.Symbol + ")", - Decimals: int(dbAsset.AssetObj.Precision), - Symbol: dbAsset.AssetObj.Symbol, - BalanceSat: (*bchain.Amount)(ownerBalance), - TotalReceivedSat: (*bchain.Amount)(totalOwnerAssetReceived), - TotalSentSat: (*bchain.Amount)(v.SentSat), - Contract: assetGuid, - Transfers: v.Transfers, - ContractIndex: assetGuid, - }) - ownerFound = true - } - } totalAssetReceived := bchain.ReceivedSatFromBalances(v.BalanceSat, v.SentSat) assetGuid := strconv.FormatUint(uint64(k), 10) tokens = append(tokens, &bchain.Token{ @@ -1307,7 +1284,6 @@ func (w *Worker) GetAsset(asset string, page int, txsOnPage int, option AccountD AssetDetails: &AssetSpecific{ AssetGuid: assetGuid, Symbol: dbAsset.AssetObj.Symbol, - AddrStr: dbAsset.AddrDesc.String(), Contract: "0x" + hex.EncodeToString(dbAsset.AssetObj.Contract), Balance: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.Balance)), TotalSupply: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.TotalSupply)), @@ -1734,7 +1710,6 @@ func (w *Worker) GetAddressUtxo(address string, onlyConfirmed bool) (Utxos, erro assetDetails := &AssetSpecific{ AssetGuid: a.AssetInfo.AssetGuid, Symbol: dbAsset.AssetObj.Symbol, - AddrStr: dbAsset.AddrDesc.String(), Contract: "0x" + hex.EncodeToString(dbAsset.AssetObj.Contract), Balance: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.Balance)), TotalSupply: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.TotalSupply)), diff --git a/api/xpub.go b/api/xpub.go index 8632c29a..f2418117 100644 --- a/api/xpub.go +++ b/api/xpub.go @@ -241,11 +241,9 @@ func (w *Worker) tokenFromXpubAddress(data *xpubData, ad *xpubAddress, changeInd a, _, _ := w.chainParser.GetAddressesFromAddrDesc(ad.addrDesc) numAssetBalances := 0 if ad.balance != nil { - // + 1 for owner asset for unallocated token - numAssetBalances = 1 + len(ad.balance.AssetBalances) + numAssetBalances = len(ad.balance.AssetBalances) } - // +1 for base token always appended - tokens := make(bchain.Tokens, 0, 1+numAssetBalances) + tokens := make(bchain.Tokens, 0, numAssetBalances) var address string if len(a) > 0 { address = a[0] @@ -258,37 +256,12 @@ func (w *Worker) tokenFromXpubAddress(data *xpubData, ad *xpubAddress, changeInd balance = &ad.balance.BalanceSat totalSent = &ad.balance.SentSat totalReceived = ad.balance.ReceivedSat() - // for asset tokens - var ownerFound bool = false for k, v := range ad.balance.AssetBalances { dbAsset, errAsset := w.db.GetAsset(k, nil) if errAsset != nil || dbAsset == nil { return nil, errAsset } - if !ownerFound { - // add token as unallocated if address matches asset owner address - if bytes.Equal(ad.addrDesc, dbAsset.AddrDesc) { - ownerBalance := big.NewInt(dbAsset.AssetObj.Balance) - totalOwnerAssetReceived := bchain.ReceivedSatFromBalances(ownerBalance, v.SentSat) - assetGuid := strconv.FormatUint(uint64(k), 10) - tokens = append(tokens, &bchain.Token{ - Type: bchain.SPTUnallocatedTokenType, - Name: address, - Decimals: int(dbAsset.AssetObj.Precision), - Symbol: dbAsset.AssetObj.Symbol, - BalanceSat: (*bchain.Amount)(ownerBalance), - TotalReceivedSat: (*bchain.Amount)(totalOwnerAssetReceived), - TotalSentSat: (*bchain.Amount)(v.SentSat), - Path: fmt.Sprintf("%s/%d/%d", data.basePath, changeIndex, index), - Contract: assetGuid, - Transfers: v.Transfers, - ContractIndex: assetGuid, - }) - ownerFound = true - } - } totalAssetReceived := bchain.ReceivedSatFromBalances(v.BalanceSat, v.SentSat) - // add token as unallocated if address matches asset owner address other wise its allocated assetGuid := strconv.FormatUint(uint64(k), 10) tokens = append(tokens, &bchain.Token{ Type: bchain.SPTTokenType, @@ -710,7 +683,6 @@ func (w *Worker) GetXpubUtxo(xpub string, onlyConfirmed bool, gap int) (Utxos, e assetDetails := &AssetSpecific{ AssetGuid: a.AssetInfo.AssetGuid, Symbol: dbAsset.AssetObj.Symbol, - AddrStr: dbAsset.AddrDesc.String(), Contract: "0x" + hex.EncodeToString(dbAsset.AssetObj.Contract), Balance: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.Balance)), TotalSupply: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.TotalSupply)), diff --git a/bchain/baseparser.go b/bchain/baseparser.go index ab0cfb76..9c072c7c 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -359,6 +359,9 @@ func (p *BaseParser) UnpackAssetTxIndex(buf []byte) []*TxAssetIndex { func (p *BaseParser) GetAssetFromData(sptData []byte) (*Asset, error) { return nil, errors.New("Not supported") } +func (p *SyscoinParser) GetAssetFromDesc(addrDesc *bchain.AddressDescriptor) (*bchain.Asset, error) { + return nil, errors.New("Not supported") +} func (p *BaseParser) GetAllocationFromTx(tx *Tx) (*AssetAllocation, error) { return nil, errors.New("Not supported") } diff --git a/bchain/coins/sys/syscoinparser.go b/bchain/coins/sys/syscoinparser.go index 6dce3109..8e1937cd 100644 --- a/bchain/coins/sys/syscoinparser.go +++ b/bchain/coins/sys/syscoinparser.go @@ -279,6 +279,25 @@ func (p *SyscoinParser) GetAllocationFromTx(tx *bchain.Tx) (*bchain.AssetAllocat return &assetAllocation, nil } +func (p *SyscoinParser) GetAssetFromDesc(addrDesc *bchain.AddressDescriptor) (*bchain.Asset, error) { + script, err := p.GetScriptFromAddrDesc(addrDesc) + if err != nil { + return nil, err + } + sptData := p.TryGetOPReturn(script) + if sptData == nil { + return nil, errors.New("OP_RETURN empty") + } + + var asset bchain.Asset + r := bytes.NewReader(sptData) + err := asset.AssetObj.Deserialize(r) + if err != nil { + return nil, err + } + return &asset, nil +} + func (p *SyscoinParser) GetAssetFromData(sptData []byte) (*bchain.Asset, error) { var asset bchain.Asset r := bytes.NewReader(sptData) diff --git a/bchain/types.go b/bchain/types.go index f3cbc196..929929c4 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -450,7 +450,6 @@ const XPUBAddressTokenType TokenType = "XPUBAddress" // Syscoin SPT transaction const SPTNoneType TokenType = "Syscoin" const SPTTokenType TokenType = "SPTAllocated" -const SPTUnallocatedTokenType TokenType = "SPTUnallocated" const SPTUnknownType TokenType = "SPTUnknown" const SPTAssetActivateType TokenType = "SPTAssetActivate" const SPTAssetUpdateType TokenType = "SPTAssetUpdate" @@ -520,7 +519,6 @@ type AssetAllocation struct { type Asset struct { Transactions uint32 AssetObj wire.AssetType - AddrDesc AddressDescriptor } // Assets is array of Asset type Assets []Asset @@ -762,6 +760,7 @@ type BlockChainParser interface { PackAsset(asset *Asset) ([]byte, error) UnpackAsset(buf []byte) (*Asset, error) GetAssetFromData(sptData []byte) (*Asset, error) + GetAssetFromDesc(addrDesc *AddressDescriptor) (*Asset, error) GetAllocationFromTx(tx *Tx) (*AssetAllocation, error) LoadAssets(tx *Tx) error AppendAssetInfo(assetInfo *AssetInfo, buf []byte, varBuf []byte) []byte diff --git a/db/rocksdb.go b/db/rocksdb.go index 776baf89..9e994b55 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -512,10 +512,8 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses bch blockTxAssetAddresses := make(bchain.TxAssetAddressMap) // first process all outputs so that inputs can refer to txs in this block for txi := range block.Txs { - var addrDescData *bchain.AddressDescriptor = nil - var addrDescOwner *bchain.AddressDescriptor = nil - var assetGuid uint32 = 0 tx := &block.Txs[txi] + var asset *bchain.Asset = nil isActivate := d.chainParser.IsAssetActivateTx(tx.Version) isAssetTx := d.chainParser.IsAssetTx(tx.Version) btxID, err := d.chainParser.PackTxid(tx.Txid) @@ -593,19 +591,13 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses bch if err != nil { return err } - // replace asset ownership with this addrDesc in ConnectAssetOutput, this should be the change address - if isAssetTx && assetGuid == 0 && tao.AssetInfo.ValueSat.Int64() == 0 { - assetGuid = tao.AssetInfo.AssetGuid - addrDescOwner = &addrDesc - } } - } else if isAssetTx && addrDesc[0] == txscript.OP_RETURN { - // if opreturn save data for later disconnecting output - addrDescData = &addrDesc + } else if isAssetTx && asset == nil && addrDesc[0] == txscript.OP_RETURN { + asset = d.chainParser.GetAssetFromDesc(addrDesc) } } - if assetGuid > 0 && addrDescOwner != nil && addrDescData != nil { - err := d.ConnectAssetOutput(addrDescData, addrDescOwner, isActivate, isAssetTx, assetGuid, assets) + if asset != nil { + err := d.ConnectAssetOutput(asset, isActivate, isAssetTx, assets) if err != nil { return err } @@ -1026,7 +1018,6 @@ func (d *RocksDB) disconnectTxAddressesInputs(wb *gorocksdb.WriteBatch, btxID [] var err error var addrDesc *bchain.AddressDescriptor = nil isAssetTx := d.chainParser.IsAssetTx(txa.Version) - var assetGuid uint32 = 0 for i, t := range txa.Inputs { if len(t.AddrDesc) > 0 { input := &inputs[i] @@ -1081,11 +1072,6 @@ func (d *RocksDB) disconnectTxAddressesInputs(wb *gorocksdb.WriteBatch, btxID [] if err != nil { return err } - // if asset tx save ownership addrDesc for later disconnect when we replace the addrDesc of asset to this one - if isAssetTx && assetGuid == 0 && t.AssetInfo.ValueSat.Int64() == 0 { - assetGuid = t.AssetInfo.AssetGuid - addrDesc = &t.AddrDesc - } } } else { ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.AddrDesc) @@ -1094,12 +1080,6 @@ func (d *RocksDB) disconnectTxAddressesInputs(wb *gorocksdb.WriteBatch, btxID [] } } } - if addrDesc != nil { - err := d.DisconnectAssetInput(addrDesc, assets, assetGuid) - if err != nil { - return err - } - } return nil } @@ -1110,8 +1090,6 @@ func (d *RocksDB) disconnectTxAddressesOutputs(wb *gorocksdb.WriteBatch, btxID [ assets map[uint32]*bchain.Asset, blockTxAssetAddresses bchain.TxAssetAddressMap) error { var addrDesc *bchain.AddressDescriptor = nil isActivate := d.chainParser.IsAssetActivateTx(txa.Version) - isAssetTx := d.chainParser.IsAssetTx(txa.Version) - var assetGuid uint32 = 0 for i, t := range txa.Outputs { if len(t.AddrDesc) > 0 { exist := addressFoundInTx(t.AddrDesc, btxID) @@ -1142,30 +1120,24 @@ func (d *RocksDB) disconnectTxAddressesOutputs(wb *gorocksdb.WriteBatch, btxID [ if err != nil { return err } - // save it for later - if assetGuid == 0 { - assetGuid = t.AssetInfo.AssetGuid - } } } else { ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.AddrDesc) glog.Warningf("Balance for address %s (%s) not found", ad, t.AddrDesc) } - } else if isAssetTx && t.AddrDesc[0] == txscript.OP_RETURN { - // if opreturn save data for later disconnecting output - addrDesc = &t.AddrDesc + } else if isAssetTx && asset == nil && t.AddrDesc[0] == txscript.OP_RETURN { + asset = d.chainParser.GetAssetFromDesc(&t.AddrDesc) } } } - if assetGuid > 0 && addrDesc != nil { - err := d.DisconnectAssetOutput(addrDesc, isActivate, assets, assetGuid) + if asset != nil { + err := d.DisconnectAssetOutput(asset, isActivate, assets) if err != nil { return err } } return nil } - func (d *RocksDB) disconnectBlock(height uint32, blockTxs []bchain.BlockTxs) error { wb := gorocksdb.NewWriteBatch() defer wb.Destroy() diff --git a/db/rocksdb_syscointype.go b/db/rocksdb_syscointype.go index 7024d84a..e91929ac 100644 --- a/db/rocksdb_syscointype.go +++ b/db/rocksdb_syscointype.go @@ -157,20 +157,9 @@ func (d *RocksDB) ConnectAllocationOutput(addrDesc* bchain.AddressDescriptor, he return nil } -func (d *RocksDB) ConnectAssetOutput(addrDescData *bchain.AddressDescriptor, addrDesc *bchain.AddressDescriptor, isActivate bool, isAssetTx bool, assetGuid uint32, assets map[uint32]*bchain.Asset) error { - script, err := d.chainParser.GetScriptFromAddrDesc(*addrDescData) - if err != nil { - return err - } - sptData := d.chainParser.TryGetOPReturn(script) - if sptData == nil { - return errors.New("ConnectAssetOutput could not parse opreturn") - } - asset, err := d.chainParser.GetAssetFromData(sptData) - if err != nil { - return err - } +func (d *RocksDB) ConnectAssetOutput(asset *bchain.Asset, isActivate bool, isAssetTx bool, assets map[uint32]*bchain.Asset) error { var dBAsset* bchain.Asset = nil + assetGuid := asset.Allocation.VoutAssets[0].AssetGuid if !isActivate { dBAsset, err = d.GetAsset(assetGuid, assets) if err != nil { @@ -188,7 +177,6 @@ func (d *RocksDB) ConnectAssetOutput(addrDescData *bchain.AddressDescriptor, add if err != nil { return err } - dBAsset.AddrDesc = *addrDesc } assets[assetGuid] = dBAsset } else { @@ -226,19 +214,8 @@ func (d *RocksDB) DisconnectAllocationOutput(addrDesc *bchain.AddressDescriptor, assets[assetInfo.AssetGuid] = dBAsset return nil } -func (d *RocksDB) DisconnectAssetOutput(addrDesc *bchain.AddressDescriptor, isActivate bool, assets map[uint32]*bchain.Asset, assetGuid uint32) error { - script, err := d.chainParser.GetScriptFromAddrDesc(*addrDesc) - if err != nil { - return err - } - sptData := d.chainParser.TryGetOPReturn(script) - if sptData == nil { - return errors.New(fmt.Sprint("DisconnectAssetOutput could not parse opreturn")) - } - asset, err := d.chainParser.GetAssetFromData(sptData) - if err != nil { - return err - } +func (d *RocksDB) DisconnectAssetOutput(asset *bchain.Asset, isActivate bool, assets map[uint32]*bchain.Asset) error { + assetGuid := asset.Allocation.VoutAssets[0].AssetGuid dBAsset, err := d.GetAsset(assetGuid, assets) if dBAsset == nil || err != nil { if dBAsset == nil { @@ -279,18 +256,7 @@ func (d *RocksDB) DisconnectAllocationInput(addrDesc *bchain.AddressDescriptor, assets[assetInfo.AssetGuid] = dBAsset return nil } -func (d *RocksDB) DisconnectAssetInput(addrDesc *bchain.AddressDescriptor, assets map[uint32]*bchain.Asset, assetGuid uint32) error { - dBAsset, err := d.GetAsset(assetGuid, assets) - if dBAsset == nil || err != nil { - if dBAsset == nil { - return errors.New(fmt.Sprint("DisconnectAssetInput could not read asset " , assetGuid)) - } - return err - } - dBAsset.AddrDesc = *addrDesc - assets[assetGuid] = dBAsset - return nil -} + func (d *RocksDB) SetupAssetCache() error { start := time.Now() if AssetCache == nil { diff --git a/server/socketio.go b/server/socketio.go index 065609b2..48914dc1 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -630,7 +630,6 @@ func (s *SocketIoServer) getAssetHistory(asset string, opts *assetOpts) (res res res.Result.AssetDetails = &api.AssetSpecific{ AssetGuid: assetGuid, Symbol: dbAsset.AssetObj.Symbol, - AddrStr: dbAsset.AddrDesc.String(), Contract: "0x" + hex.EncodeToString(dbAsset.AssetObj.Contract), Balance: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.Balance)), TotalSupply: (*bchain.Amount)(big.NewInt(dbAsset.AssetObj.TotalSupply)), diff --git a/static/templates/address.html b/static/templates/address.html index 1244c042..b65faa7f 100644 --- a/static/templates/address.html +++ b/static/templates/address.html @@ -85,7 +85,7 @@ {{if $t.Contract}}{{$t.Contract}}{{else}}{{$t.Name}}{{end}} {{formatAmountWithDecimals $t.TotalReceivedSat $t.Decimals}} {{$t.Symbol}} {{formatAmountWithDecimals $t.TotalSentSat $t.Decimals}} {{$t.Symbol}} - {{formatAmountWithDecimals $t.BalanceSat $t.Decimals}} {{$t.Symbol}}{{- if eq $t.Type "SPTUnallocated" -}} ⚠️{{- end -}} + {{formatAmountWithDecimals $t.BalanceSat $t.Decimals}} {{$t.Symbol}} {{$t.Transfers}} {{- end -}}{{- end -}} diff --git a/static/templates/tx.html b/static/templates/tx.html index 77867d0a..6344b215 100644 --- a/static/templates/tx.html +++ b/static/templates/tx.html @@ -79,8 +79,8 @@ {{- range $tokenTransfer := $tx.TokenTransferSummary -}}{{if $tokenTransfer}} {{$tokenTransfer.Token}} - {{formatAmountWithDecimals $tokenTransfer.Value $tokenTransfer.Decimals}} {{$tokenTransfer.Symbol}}{{- if eq $tokenTransfer.Type "SPTUnallocated" -}} ⚠️{{- end -}} - {{formatAmountWithDecimals $tokenTransfer.ValueOut $tokenTransfer.Decimals}} {{$tokenTransfer.Symbol}}{{- if eq $tokenTransfer.Type "SPTUnallocated" -}} ⚠️{{- end -}} + {{formatAmountWithDecimals $tokenTransfer.Value $tokenTransfer.Decimals}} {{$tokenTransfer.Symbol}} + {{formatAmountWithDecimals $tokenTransfer.ValueOut $tokenTransfer.Decimals}} {{$tokenTransfer.Symbol}} {{- end -}}{{- end -}}