2019-01-11 03:02:26 +01:00
package manager
2017-12-28 18:14:33 +01:00
import (
2019-06-12 03:35:21 +02:00
"fmt"
2019-06-10 01:41:52 +02:00
"math"
2019-01-30 13:42:23 +01:00
"strconv"
2020-11-03 02:14:01 +01:00
"strings"
2017-12-28 18:14:33 +01:00
"time"
2019-10-10 16:50:33 +02:00
"github.com/lbryio/lbry.go/v2/extras/errors"
"github.com/lbryio/lbry.go/v2/extras/jsonrpc"
"github.com/lbryio/lbry.go/v2/extras/util"
2020-08-08 01:12:55 +02:00
"github.com/lbryio/ytsync/v5/shared"
2020-06-11 18:45:56 +02:00
"github.com/lbryio/ytsync/v5/timing"
logUtils "github.com/lbryio/ytsync/v5/util"
2020-07-27 20:48:05 +02:00
"github.com/lbryio/ytsync/v5/ytapi"
2017-12-28 18:14:33 +01:00
2020-06-11 18:45:56 +02:00
"github.com/lbryio/ytsync/v5/tags_manager"
"github.com/lbryio/ytsync/v5/thumbs"
2019-10-21 15:44:24 +02:00
2017-12-28 18:14:33 +01:00
"github.com/shopspring/decimal"
log "github.com/sirupsen/logrus"
)
2019-05-06 21:56:56 +02:00
func ( s * Sync ) enableAddressReuse ( ) error {
2019-12-08 17:48:24 +01:00
accountsResponse , err := s . daemon . AccountList ( 1 , 50 )
2019-05-06 21:56:56 +02:00
if err != nil {
return errors . Err ( err )
}
2019-12-08 17:48:24 +01:00
accounts := make ( [ ] jsonrpc . Account , 0 , len ( accountsResponse . Items ) )
ledger := "lbc_mainnet"
2019-08-04 00:34:48 +02:00
if logUtils . IsRegTest ( ) {
2019-12-08 17:48:24 +01:00
ledger = "lbc_regtest"
2019-05-06 21:56:56 +02:00
}
2019-12-08 17:48:24 +01:00
for _ , a := range accountsResponse . Items {
if * a . Ledger == ledger {
accounts = append ( accounts , a )
}
}
2019-05-06 21:56:56 +02:00
for _ , a := range accounts {
_ , err = s . daemon . AccountSet ( a . ID , jsonrpc . AccountSettings {
2019-06-12 22:42:42 +02:00
ChangeMaxUses : util . PtrToInt ( 1000 ) ,
ReceivingMaxUses : util . PtrToInt ( 100 ) ,
2019-05-06 21:56:56 +02:00
} )
if err != nil {
return errors . Err ( err )
}
}
return nil
}
2017-12-28 18:14:33 +01:00
func ( s * Sync ) walletSetup ( ) error {
2020-05-19 23:13:01 +02:00
start := time . Now ( )
defer func ( start time . Time ) {
timing . TimedComponent ( "walletSetup" ) . Add ( time . Since ( start ) )
} ( start )
2019-06-12 03:17:59 +02:00
//prevent unnecessary concurrent execution and publishing while refilling/reallocating UTXOs
2018-08-14 16:48:55 +02:00
s . walletMux . Lock ( )
defer s . walletMux . Unlock ( )
2018-01-10 23:07:16 +01:00
err := s . ensureChannelOwnership ( )
if err != nil {
return err
}
2019-01-30 13:42:23 +01:00
balanceResp , err := s . daemon . AccountBalance ( nil )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if balanceResp == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2017-12-28 18:14:33 +01:00
}
2019-08-21 20:01:24 +02:00
balance , err := strconv . ParseFloat ( balanceResp . Available . String ( ) , 64 )
2019-01-30 13:42:23 +01:00
if err != nil {
return errors . Err ( err )
}
log . Debugf ( "Starting balance is %.4f" , balance )
2017-12-28 18:14:33 +01:00
2020-08-21 00:15:14 +02:00
videosOnYoutube := int ( s . DbChannelData . TotalVideos )
2019-02-15 14:11:38 +01:00
2019-06-12 03:17:59 +02:00
log . Debugf ( "Source channel has %d videos" , videosOnYoutube )
if videosOnYoutube == 0 {
2018-06-15 23:03:28 +02:00
return nil
}
2017-12-28 18:14:33 +01:00
2018-08-23 00:28:31 +02:00
s . syncedVideosMux . RLock ( )
2019-06-12 03:17:59 +02:00
publishedCount := 0
notUpgradedCount := 0
failedCount := 0
for _ , sv := range s . syncedVideos {
if sv . Published {
publishedCount ++
if sv . MetadataVersion < 2 {
notUpgradedCount ++
}
} else {
failedCount ++
}
}
2018-08-23 00:28:31 +02:00
s . syncedVideosMux . RUnlock ( )
2017-12-28 18:14:33 +01:00
2019-06-22 12:08:11 +02:00
log . Debugf ( "We already allocated credits for %d published videos and %d failed videos" , publishedCount , failedCount )
2018-07-31 01:19:12 +02:00
2020-11-19 03:11:23 +01:00
if videosOnYoutube > s . Manager . CliFlags . VideosToSync ( s . DbChannelData . TotalSubscribers ) {
videosOnYoutube = s . Manager . CliFlags . VideosToSync ( s . DbChannelData . TotalSubscribers )
2019-06-12 03:17:59 +02:00
}
2019-06-22 12:08:11 +02:00
unallocatedVideos := videosOnYoutube - ( publishedCount + failedCount )
2022-01-26 07:43:09 +01:00
if unallocatedVideos < 0 {
unallocatedVideos = 0
}
2019-09-04 19:24:11 +02:00
channelFee := channelClaimAmount
2020-08-08 01:12:55 +02:00
channelAlreadyClaimed := s . DbChannelData . ChannelClaimID != ""
2019-09-04 19:24:11 +02:00
if channelAlreadyClaimed {
channelFee = 0.0
}
requiredBalance := float64 ( unallocatedVideos ) * ( publishAmount + estimatedMaxTxFee ) + channelFee
2020-08-08 01:12:55 +02:00
if s . Manager . CliFlags . UpgradeMetadata {
2022-01-26 07:11:26 +01:00
requiredBalance += float64 ( notUpgradedCount ) * estimatedMaxTxFee
2019-05-24 19:01:16 +02:00
}
2019-06-12 03:17:59 +02:00
refillAmount := 0.0
if balance < requiredBalance || balance < minimumAccountBalance {
2019-09-04 19:24:11 +02:00
refillAmount = math . Max ( math . Max ( requiredBalance - balance , minimumAccountBalance - balance ) , minimumRefillAmount )
2018-05-07 22:26:46 +02:00
}
2018-03-12 21:58:37 +01:00
2020-08-08 01:12:55 +02:00
if s . Manager . CliFlags . Refill > 0 {
refillAmount += float64 ( s . Manager . CliFlags . Refill )
2018-03-12 21:58:37 +01:00
}
2017-12-28 18:14:33 +01:00
2019-06-12 03:17:59 +02:00
if refillAmount > 0 {
err := s . addCredits ( refillAmount )
2019-01-30 13:42:23 +01:00
if err != nil {
return errors . Err ( err )
}
2022-01-26 07:11:26 +01:00
} else if balance > requiredBalance {
extraLBC := balance - requiredBalance
if extraLBC > 5 {
sendBackAmount := extraLBC - 1
2022-01-26 07:43:09 +01:00
logUtils . SendInfoToSlack ( "channel %s has %.1f credits which is %.1f more than it requires (%.1f). We should send at least %.1f that back." , s . DbChannelData . ChannelId , balance , extraLBC , requiredBalance , sendBackAmount )
2022-01-26 07:11:26 +01:00
}
2017-12-28 18:14:33 +01:00
}
2019-12-08 17:48:24 +01:00
claimAddress , err := s . daemon . AddressList ( nil , nil , 1 , 20 )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if claimAddress == nil {
2019-12-08 17:48:24 +01:00
return errors . Err ( "could not get an address" )
2017-12-28 18:14:33 +01:00
}
2021-03-23 01:18:26 +01:00
if s . DbChannelData . PublishAddress . Address == "" || ! s . shouldTransfer ( ) {
s . DbChannelData . PublishAddress . Address = string ( claimAddress . Items [ 0 ] . Address )
s . DbChannelData . PublishAddress . IsMine = true
2017-12-28 18:14:33 +01:00
}
2021-03-23 01:18:26 +01:00
if s . DbChannelData . PublishAddress . Address == "" {
2020-08-08 01:12:55 +02:00
return errors . Err ( "found blank claim address" )
2019-08-16 05:34:25 +02:00
}
2017-12-28 18:14:33 +01:00
err = s . ensureEnoughUTXOs ( )
if err != nil {
return err
}
return nil
}
2019-10-16 19:38:45 +02:00
2019-10-01 16:55:43 +02:00
func ( s * Sync ) getDefaultAccount ( ) ( string , error ) {
2020-05-19 23:13:01 +02:00
start := time . Now ( )
defer func ( start time . Time ) {
timing . TimedComponent ( "getDefaultAccount" ) . Add ( time . Since ( start ) )
} ( start )
2019-10-16 19:38:45 +02:00
if s . defaultAccountID == "" {
2019-12-08 17:48:24 +01:00
accountsResponse , err := s . daemon . AccountList ( 1 , 50 )
2019-10-16 19:38:45 +02:00
if err != nil {
return "" , errors . Err ( err )
}
2019-12-08 17:48:24 +01:00
ledger := "lbc_mainnet"
2019-10-16 19:38:45 +02:00
if logUtils . IsRegTest ( ) {
2019-12-08 17:48:24 +01:00
ledger = "lbc_regtest"
2019-10-16 19:38:45 +02:00
}
2019-12-08 17:48:24 +01:00
for _ , a := range accountsResponse . Items {
if * a . Ledger == ledger {
if a . IsDefault {
s . defaultAccountID = a . ID
break
}
2019-10-16 19:38:45 +02:00
}
}
2019-12-08 17:48:24 +01:00
2019-10-16 19:38:45 +02:00
if s . defaultAccountID == "" {
return "" , errors . Err ( "No default account found" )
2019-01-30 13:42:23 +01:00
}
}
2019-10-16 19:38:45 +02:00
return s . defaultAccountID , nil
2019-10-01 16:55:43 +02:00
}
func ( s * Sync ) ensureEnoughUTXOs ( ) error {
2020-05-19 23:13:01 +02:00
start := time . Now ( )
defer func ( start time . Time ) {
timing . TimedComponent ( "ensureEnoughUTXOs" ) . Add ( time . Since ( start ) )
} ( start )
2019-10-01 16:55:43 +02:00
defaultAccount , err := s . getDefaultAccount ( )
if err != nil {
return err
2019-01-30 13:42:23 +01:00
}
2019-12-08 17:48:24 +01:00
utxolist , err := s . daemon . UTXOList ( & defaultAccount , 1 , 10000 )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if utxolist == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2017-12-28 18:14:33 +01:00
}
2018-05-05 18:18:44 +02:00
target := 40
2018-08-10 02:59:52 +02:00
slack := int ( float32 ( 0.1 ) * float32 ( target ) )
2017-12-28 18:14:33 +01:00
count := 0
2019-06-26 02:45:27 +02:00
confirmedCount := 0
2017-12-28 18:14:33 +01:00
2019-12-08 17:48:24 +01:00
for _ , utxo := range utxolist . Items {
2019-01-30 13:42:23 +01:00
amount , _ := strconv . ParseFloat ( utxo . Amount , 64 )
2020-04-01 04:44:05 +02:00
if utxo . IsMyOutput && utxo . Type == "payment" && amount > 0.001 {
2019-06-26 02:45:27 +02:00
if utxo . Confirmations > 0 {
confirmedCount ++
}
2017-12-28 18:14:33 +01:00
count ++
}
}
2019-06-26 02:45:27 +02:00
log . Infof ( "utxo count: %d (%d confirmed)" , count , confirmedCount )
UTXOWaitThreshold := 16
2018-08-08 23:59:59 +02:00
if count < target - slack {
2019-01-30 13:42:23 +01:00
balance , err := s . daemon . AccountBalance ( & defaultAccount )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if balance == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2017-12-28 18:14:33 +01:00
}
2019-08-21 20:01:24 +02:00
balanceAmount , err := strconv . ParseFloat ( balance . Available . String ( ) , 64 )
2019-01-30 13:42:23 +01:00
if err != nil {
return errors . Err ( err )
}
2021-01-12 16:49:54 +01:00
//this is dumb but sometimes the balance is negative and it breaks everything, so let's check again
if balanceAmount < 0 {
log . Infof ( "negative balance of %.2f found. Waiting to retry..." , balanceAmount )
time . Sleep ( 10 * time . Second )
balanceAmount , err = strconv . ParseFloat ( balance . Available . String ( ) , 64 )
if err != nil {
return errors . Err ( err )
}
}
2019-06-12 05:33:13 +02:00
maxUTXOs := uint64 ( 500 )
2019-06-12 03:17:59 +02:00
desiredUTXOCount := uint64 ( math . Floor ( ( balanceAmount ) / 0.1 ) )
2019-06-12 05:33:13 +02:00
if desiredUTXOCount > maxUTXOs {
desiredUTXOCount = maxUTXOs
}
2020-02-24 15:52:32 +01:00
if desiredUTXOCount < uint64 ( confirmedCount ) {
return nil
}
2019-08-23 01:28:51 +02:00
availableBalance , _ := balance . Available . Float64 ( )
log . Infof ( "Splitting balance of %.3f evenly between %d UTXOs" , availableBalance , desiredUTXOCount )
2017-12-28 18:14:33 +01:00
2019-06-12 05:33:13 +02:00
broadcastFee := 0.1
prefillTx , err := s . daemon . AccountFund ( defaultAccount , defaultAccount , fmt . Sprintf ( "%.4f" , balanceAmount - broadcastFee ) , desiredUTXOCount , false )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if prefillTx == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2017-12-28 18:14:33 +01:00
}
2019-06-26 02:45:27 +02:00
if confirmedCount < UTXOWaitThreshold {
err = s . waitForNewBlock ( )
if err != nil {
return err
}
2017-12-28 18:14:33 +01:00
}
2019-06-26 02:45:27 +02:00
} else if confirmedCount < UTXOWaitThreshold {
2018-08-03 19:50:17 +02:00
log . Println ( "Waiting for previous txns to confirm" )
2018-08-03 23:19:36 +02:00
err := s . waitForNewBlock ( )
2018-08-03 19:50:17 +02:00
if err != nil {
return err
}
2017-12-28 18:14:33 +01:00
}
return nil
}
2018-08-03 23:19:36 +02:00
func ( s * Sync ) waitForNewBlock ( ) error {
2020-07-27 20:48:05 +02:00
defer func ( start time . Time ) { timing . TimedComponent ( "waitForNewBlock" ) . Add ( time . Since ( start ) ) } ( time . Now ( ) )
2019-12-08 16:31:15 +01:00
log . Printf ( "regtest: %t, docker: %t" , logUtils . IsRegTest ( ) , logUtils . IsUsingDocker ( ) )
2018-08-03 23:19:36 +02:00
status , err := s . daemon . Status ( )
if err != nil {
return err
}
2020-07-27 20:48:05 +02:00
2018-08-10 02:19:37 +02:00
for status . Wallet . Blocks == 0 || status . Wallet . BlocksBehind != 0 {
2018-08-03 23:19:36 +02:00
time . Sleep ( 5 * time . Second )
status , err = s . daemon . Status ( )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
}
2018-08-03 23:19:36 +02:00
}
2019-12-08 17:48:24 +01:00
2018-08-10 02:19:37 +02:00
currentBlock := status . Wallet . Blocks
for i := 0 ; status . Wallet . Blocks <= currentBlock ; i ++ {
2018-08-03 23:19:36 +02:00
if i % 3 == 0 {
log . Printf ( "Waiting for new block (%d)..." , currentBlock + 1 )
2017-12-28 18:14:33 +01:00
}
2019-12-08 17:48:24 +01:00
if logUtils . IsRegTest ( ) && logUtils . IsUsingDocker ( ) {
err = s . GenerateRegtestBlock ( )
if err != nil {
return err
}
}
2018-08-03 23:19:36 +02:00
time . Sleep ( 10 * time . Second )
status , err = s . daemon . Status ( )
if err != nil {
return err
2018-05-05 16:15:02 +02:00
}
2017-12-28 18:14:33 +01:00
}
2020-12-16 16:59:07 +01:00
time . Sleep ( 5 * time . Second )
2018-08-03 23:19:36 +02:00
return nil
2017-12-28 18:14:33 +01:00
}
2019-12-08 17:48:24 +01:00
func ( s * Sync ) GenerateRegtestBlock ( ) error {
2020-08-08 01:12:55 +02:00
lbrycrd , err := logUtils . GetLbrycrdClient ( s . Manager . LbrycrdDsn )
2019-12-08 17:48:24 +01:00
if err != nil {
2021-11-24 05:54:08 +01:00
return errors . Prefix ( "error getting lbrycrd client" , err )
2019-12-08 17:48:24 +01:00
}
2020-07-27 20:48:05 +02:00
2019-12-08 17:48:24 +01:00
txs , err := lbrycrd . Generate ( 1 )
if err != nil {
2021-11-24 05:54:08 +01:00
return errors . Prefix ( "error generating new block" , err )
2019-12-08 17:48:24 +01:00
}
2020-07-27 20:48:05 +02:00
2019-12-08 17:48:24 +01:00
for _ , tx := range txs {
log . Info ( "Generated tx: " , tx . String ( ) )
}
return nil
}
2017-12-28 18:14:33 +01:00
func ( s * Sync ) ensureChannelOwnership ( ) error {
2020-07-27 20:48:05 +02:00
defer func ( start time . Time ) { timing . TimedComponent ( "ensureChannelOwnership" ) . Add ( time . Since ( start ) ) } ( time . Now ( ) )
2020-08-08 01:12:55 +02:00
if s . DbChannelData . DesiredChannelName == "" {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no channel name set" )
2017-12-28 18:14:33 +01:00
}
2019-10-08 02:13:17 +02:00
2021-04-13 00:55:50 +02:00
channels , err := s . daemon . ChannelList ( nil , 1 , 500 , nil )
2017-12-28 18:14:33 +01:00
if err != nil {
return err
} else if channels == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no channel response" )
2017-12-28 18:14:33 +01:00
}
2019-08-15 19:31:43 +02:00
var channelToUse * jsonrpc . Transaction
if len ( ( * channels ) . Items ) > 0 {
2020-08-08 01:12:55 +02:00
if s . DbChannelData . ChannelClaimID == "" {
2019-01-03 17:01:00 +01:00
return errors . Err ( "this channel does not have a recorded claimID in the database. To prevent failures, updates are not supported until an entry is manually added in the database" )
}
2019-01-30 13:42:23 +01:00
for _ , c := range ( * channels ) . Items {
2019-08-15 19:31:43 +02:00
log . Debugf ( "checking listed channel %s (%s)" , c . ClaimID , c . Name )
2020-08-08 01:12:55 +02:00
if c . ClaimID != s . DbChannelData . ChannelClaimID {
2019-08-15 19:31:43 +02:00
continue
}
2020-08-08 01:12:55 +02:00
if c . Name != s . DbChannelData . DesiredChannelName {
2019-08-15 19:31:43 +02:00
return errors . Err ( "the channel in the wallet is different than the channel in the database" )
2019-01-03 17:01:00 +01:00
}
2019-08-15 19:31:43 +02:00
channelToUse = & c
break
}
if channelToUse == nil {
2020-08-08 01:12:55 +02:00
return errors . Err ( "this wallet has channels but not a single one is ours! Expected claim_id: %s (%s)" , s . DbChannelData . ChannelClaimID , s . DbChannelData . DesiredChannelName )
2019-01-03 17:01:00 +01:00
}
2020-08-08 01:12:55 +02:00
} else if s . DbChannelData . TransferState == shared . TransferStateComplete {
2020-01-14 04:10:20 +01:00
return errors . Err ( "the channel was transferred but appears to have been abandoned!" )
2020-08-08 01:12:55 +02:00
} else if s . DbChannelData . ChannelClaimID != "" {
return errors . Err ( "the database has a channel recorded (%s) but nothing was found in our control" , s . DbChannelData . ChannelClaimID )
2019-01-03 17:01:00 +01:00
}
2019-08-15 19:31:43 +02:00
2019-05-09 17:06:56 +02:00
channelUsesOldMetadata := false
2019-08-15 19:31:43 +02:00
if channelToUse != nil {
2022-08-10 17:27:27 +02:00
channelUsesOldMetadata = channelToUse . Value . GetThumbnail ( ) == nil || ( len ( channelToUse . Value . GetLanguages ( ) ) == 0 && s . DbChannelData . Language != "" )
2019-08-15 19:31:43 +02:00
if ! channelUsesOldMetadata {
return nil
2017-12-28 18:14:33 +01:00
}
}
2019-01-30 13:42:23 +01:00
balanceResp , err := s . daemon . AccountBalance ( nil )
2018-01-10 23:07:16 +01:00
if err != nil {
return err
} else if balanceResp == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2018-01-10 23:07:16 +01:00
}
2019-08-21 20:01:24 +02:00
balance , err := decimal . NewFromString ( balanceResp . Available . String ( ) )
2019-01-30 13:42:23 +01:00
if err != nil {
return errors . Err ( err )
}
2018-01-10 23:07:16 +01:00
2022-08-09 22:11:42 +02:00
if balance . LessThan ( decimal . NewFromFloat ( channelClaimAmount ) ) {
err = s . addCredits ( channelClaimAmount + estimatedMaxTxFee * 3 )
2018-12-25 01:23:40 +01:00
if err != nil {
return err
}
2018-01-10 23:07:16 +01:00
}
2020-08-08 01:12:55 +02:00
channelInfo , err := ytapi . ChannelInfo ( s . DbChannelData . ChannelId )
2019-04-19 03:22:51 +02:00
if err != nil {
2020-11-03 02:14:01 +01:00
if strings . Contains ( err . Error ( ) , "invalid character 'e' looking for beginning of value" ) {
logUtils . SendInfoToSlack ( "failed to get channel data for %s. Waiting 1 minute to retry" , s . DbChannelData . ChannelId )
time . Sleep ( 1 * time . Minute )
channelInfo , err = ytapi . ChannelInfo ( s . DbChannelData . ChannelId )
if err != nil {
return err
}
} else {
return err
}
2019-04-19 03:22:51 +02:00
}
2020-08-04 00:55:26 +02:00
thumbnail := channelInfo . Header . C4TabbedHeaderRenderer . Avatar . Thumbnails [ len ( channelInfo . Header . C4TabbedHeaderRenderer . Avatar . Thumbnails ) - 1 ] . URL
2021-11-24 05:54:08 +01:00
thumbnailURL , err := thumbs . MirrorThumbnail ( thumbnail , s . DbChannelData . ChannelId )
2019-04-19 03:22:51 +02:00
if err != nil {
return err
}
2019-05-24 19:01:16 +02:00
2019-05-28 22:40:31 +02:00
var bannerURL * string
2020-08-04 00:55:26 +02:00
if channelInfo . Header . C4TabbedHeaderRenderer . Banner . Thumbnails != nil {
2020-08-08 01:12:55 +02:00
bURL , err := thumbs . MirrorThumbnail ( channelInfo . Header . C4TabbedHeaderRenderer . Banner . Thumbnails [ len ( channelInfo . Header . C4TabbedHeaderRenderer . Banner . Thumbnails ) - 1 ] . URL ,
"banner-" + s . DbChannelData . ChannelId ,
)
2019-05-24 19:01:16 +02:00
if err != nil {
return err
}
bannerURL = & bURL
}
2019-04-19 03:22:51 +02:00
var languages [ ] string = nil
2022-08-09 22:11:42 +02:00
if s . DbChannelData . Language != "" {
languages = [ ] string { s . DbChannelData . Language }
}
2022-08-10 18:23:05 +02:00
2019-04-19 03:22:51 +02:00
var locations [ ] jsonrpc . Location = nil
2020-08-04 00:55:26 +02:00
if channelInfo . Topbar . DesktopTopbarRenderer . CountryCode != "" {
2020-08-08 02:31:26 +02:00
locations = [ ] jsonrpc . Location { { Country : & channelInfo . Topbar . DesktopTopbarRenderer . CountryCode } }
2019-04-19 03:22:51 +02:00
}
2019-05-09 17:06:56 +02:00
var c * jsonrpc . TransactionSummary
2022-08-10 18:23:05 +02:00
var recoveredChannelClaimID string
2019-06-04 22:21:40 +02:00
claimCreateOptions := jsonrpc . ClaimCreateOptions {
2020-08-04 00:55:26 +02:00
Title : & channelInfo . Microformat . MicroformatDataRenderer . Title ,
2020-08-31 21:27:39 +02:00
Description : & channelInfo . Metadata . ChannelMetadataRenderer . Description ,
2020-08-08 01:12:55 +02:00
Tags : tags_manager . GetTagsForChannel ( s . DbChannelData . ChannelId ) ,
2019-06-04 22:21:40 +02:00
Languages : languages ,
Locations : locations ,
ThumbnailURL : & thumbnailURL ,
}
2019-05-09 17:06:56 +02:00
if channelUsesOldMetadata {
2022-08-15 22:42:06 +02:00
da , err := s . getDefaultAccount ( )
if err != nil {
return err
}
2020-08-08 01:12:55 +02:00
if s . DbChannelData . TransferState <= 1 {
c , err = s . daemon . ChannelUpdate ( s . DbChannelData . ChannelClaimID , jsonrpc . ChannelUpdateOptions {
2020-03-27 18:16:35 +01:00
ClearTags : util . PtrToBool ( true ) ,
ClearLocations : util . PtrToBool ( true ) ,
ClearLanguages : util . PtrToBool ( true ) ,
ChannelCreateOptions : jsonrpc . ChannelCreateOptions {
2022-08-15 22:42:06 +02:00
AccountID : & da ,
FundingAccountIDs : [ ] string {
da ,
} ,
2020-03-27 18:16:35 +01:00
ClaimCreateOptions : claimCreateOptions ,
CoverURL : bannerURL ,
} ,
} )
} else {
2020-08-08 01:12:55 +02:00
logUtils . SendInfoToSlack ( "%s (%s) has a channel with old metadata but isn't in our control anymore. Ignoring" , s . DbChannelData . DesiredChannelName , s . DbChannelData . ChannelClaimID )
2020-03-27 18:16:35 +01:00
return nil
}
2019-05-09 17:06:56 +02:00
} else {
2022-08-09 22:17:03 +02:00
c , err = s . daemon . ChannelCreate ( s . DbChannelData . DesiredChannelName , channelClaimAmount , jsonrpc . ChannelCreateOptions {
2019-06-04 22:21:40 +02:00
ClaimCreateOptions : claimCreateOptions ,
CoverURL : bannerURL ,
2019-05-09 17:06:56 +02:00
} )
2022-08-10 18:23:05 +02:00
if err != nil {
claimId , err2 := s . getChannelClaimIDForTimedOutCreation ( )
if err2 != nil {
err = errors . Prefix ( err2 . Error ( ) , err )
} else {
recoveredChannelClaimID = claimId
}
}
2019-05-09 17:06:56 +02:00
}
2017-12-28 18:14:33 +01:00
if err != nil {
return err
}
2022-08-10 18:23:05 +02:00
if recoveredChannelClaimID != "" {
s . DbChannelData . ChannelClaimID = recoveredChannelClaimID
} else {
s . DbChannelData . ChannelClaimID = c . Outputs [ 0 ] . ClaimID
}
2020-08-08 01:12:55 +02:00
return s . Manager . ApiConfig . SetChannelClaimID ( s . DbChannelData . ChannelId , s . DbChannelData . ChannelClaimID )
2017-12-28 18:14:33 +01:00
}
2022-08-10 18:23:05 +02:00
//getChannelClaimIDForTimedOutCreation is a raw function that returns the only channel that exists in the wallet
// this is used because the SDK sucks and can't figure out when to return when creating a claim...
func ( s * Sync ) getChannelClaimIDForTimedOutCreation ( ) ( string , error ) {
channels , err := s . daemon . ChannelList ( nil , 1 , 500 , nil )
if err != nil {
return "" , err
} else if channels == nil {
return "" , errors . Err ( "no channel response" )
}
if len ( ( * channels ) . Items ) != 1 {
return "" , errors . Err ( "more than one channel found when trying to recover from SDK failure in creating the channel" )
}
desiredChannel := ( * channels ) . Items [ 0 ]
if desiredChannel . Name != s . DbChannelData . DesiredChannelName {
return "" , errors . Err ( "the channel found in the wallet has a different name than the one we expected" )
}
return desiredChannel . ClaimID , nil
}
2018-01-10 23:07:16 +01:00
func ( s * Sync ) addCredits ( amountToAdd float64 ) error {
2020-05-19 23:13:01 +02:00
start := time . Now ( )
defer func ( start time . Time ) {
timing . TimedComponent ( "addCredits" ) . Add ( time . Since ( start ) )
} ( start )
2018-01-10 23:07:16 +01:00
log . Printf ( "Adding %f credits" , amountToAdd )
2020-08-08 01:12:55 +02:00
lbrycrdd , err := logUtils . GetLbrycrdClient ( s . Manager . LbrycrdDsn )
2019-08-01 04:42:22 +02:00
if err != nil {
return err
2018-01-10 23:07:16 +01:00
}
2019-12-24 05:00:16 +01:00
defaultAccount , err := s . getDefaultAccount ( )
if err != nil {
return err
}
addressResp , err := s . daemon . AddressUnused ( & defaultAccount )
2018-01-10 23:07:16 +01:00
if err != nil {
return err
} else if addressResp == nil {
2018-03-09 17:47:38 +01:00
return errors . Err ( "no response" )
2018-01-10 23:07:16 +01:00
}
address := string ( * addressResp )
_ , err = lbrycrdd . SimpleSend ( address , amountToAdd )
if err != nil {
return err
}
wait := 15 * time . Second
log . Println ( "Waiting " + wait . String ( ) + " for lbryum to let us know we have the new transaction" )
time . Sleep ( wait )
2018-06-15 23:03:28 +02:00
return nil
2018-01-10 23:07:16 +01:00
}