github.com/deso-protocol/core@v1.2.9/lib/block_view_creator_coin_test.go (about)

     1  package lib
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/dgraph-io/badger/v3"
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  	"testing"
     9  )
    10  
    11  type _CreatorCoinTestData struct {
    12  	// These are the transaction params
    13  	UpdaterPublicKeyBase58Check  string
    14  	UpdaterPrivateKeyBase58Check string
    15  	ProfilePublicKeyBase58Check  string
    16  	OperationType                CreatorCoinOperationType
    17  	DeSoToSellNanos              uint64
    18  	CreatorCoinToSellNanos       uint64
    19  	DeSoToAddNanos               uint64
    20  	MinDeSoExpectedNanos         uint64
    21  	MinCreatorCoinExpectedNanos  uint64
    22  
    23  	// The Diamond info
    24  	DiamondPostHashIndex int
    25  	DiamondLevel         int64
    26  
    27  	// SubmitPost info
    28  	SubmitPostBody string
    29  	PostIsHidden   bool
    30  	// We save all post hashes of posts that are created into
    31  	// an array ordered by the time when they were created. To
    32  	// reference a previous post, one just needs to set these
    33  	// indexes to the index of the post in this array.
    34  	PostHashToModifyIndex int
    35  	ParentPostHashIndex   int
    36  
    37  	// For creator coin transfers.
    38  	CreatorCoinToTransferNanos   uint64
    39  	ReceiverPublicKeyBase58Check string
    40  
    41  	// The type of txn we're having the helper execute. When unset, this defaults to
    42  	// a CreatorCoin transaction to avoid having to change existing code.
    43  	TxnType TxnType
    44  
    45  	// Extra fields for UpdateProfile txns
    46  	ProfileUsername           string
    47  	ProfileDescription        string
    48  	ProfilePic                string
    49  	ProfileCreatorBasisPoints uint64
    50  	ProfileIsHidden           bool
    51  
    52  	// Extra fields for SwapIdentity
    53  	FromPublicKey []byte
    54  	ToPublicKey   []byte
    55  
    56  	// Extra fields for Follow
    57  	FollowedPublicKey []byte
    58  	IsUnfollow        bool
    59  
    60  	// When set, the checks are skipped
    61  	SkipChecks bool
    62  
    63  	// These are the expectations (skipped when SkipChecks is set)
    64  	CoinsInCirculationNanos uint64
    65  	DeSoLockedNanos         uint64
    66  	CoinWatermarkNanos      uint64
    67  	m0CCBalance             uint64
    68  	m1CCBalance             uint64
    69  	m2CCBalance             uint64
    70  	m3CCBalance             uint64
    71  	m4CCBalance             uint64
    72  	m5CCBalance             uint64
    73  	m6CCBalance             uint64
    74  	m0DeSoBalance           uint64
    75  	m1DeSoBalance           uint64
    76  	m2DeSoBalance           uint64
    77  	m3DeSoBalance           uint64
    78  	m4DeSoBalance           uint64
    79  	m5DeSoBalance           uint64
    80  	m6DeSoBalance           uint64
    81  	m0HasPurchased          bool
    82  	m1HasPurchased          bool
    83  	m2HasPurchased          bool
    84  	m3HasPurchased          bool
    85  	m4HasPurchased          bool
    86  	m5HasPurchased          bool
    87  	m6HasPurchased          bool
    88  
    89  	// These fields allow us to fetch and check profile data during validation.
    90  	ProfilesToCheckPublicKeysBase58Check []string
    91  	ProfilesToCheckUsernames             []string
    92  	ProfilesToCheckDescriptions          []string
    93  	ProfilesToCheckProfilePic            []string
    94  
    95  	// These fields allow us to check follows
    96  	FollowPublicKeysToCheck           []string
    97  	FollowPublicKeysUserIsFollowing   []map[string]bool
    98  	FollowPublicKeysFollowingThisUser []map[string]bool
    99  }
   100  
   101  // Sets up a test harness for running and checking various permutations
   102  // of buy/sell transactions on creator coins. m0 is the creator coin being
   103  // traded and m1 and m2 are other users.
   104  func _helpTestCreatorCoinBuySell(
   105  	t *testing.T,
   106  	creatorCoinTests []*_CreatorCoinTestData,
   107  	desoFounderReward bool) {
   108  
   109  	// These are block heights where deso forked.
   110  	SalomonFixBlockHeight = 0
   111  	BuyCreatorCoinAfterDeletedBalanceEntryFixBlockHeight = 0
   112  	DeSoFounderRewardBlockHeight = 0
   113  	if !desoFounderReward {
   114  		DeSoFounderRewardBlockHeight = 1e9
   115  	}
   116  
   117  	// Set up a blockchain
   118  	assert := assert.New(t)
   119  	require := require.New(t)
   120  	_, _ = assert, require
   121  
   122  	chain, params, db := NewLowDifficultyBlockchain()
   123  	mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/)
   124  	feeRateNanosPerKB := uint64(11)
   125  	_, _ = mempool, miner
   126  
   127  	// Create a paramUpdater for this test
   128  	params.ParamUpdaterPublicKeys[MakePkMapKey(paramUpdaterPkBytes)] = true
   129  
   130  	// Give paramUpdater some mony
   131  	_, _, _ = _doBasicTransferWithViewFlush(
   132  		t, chain, db, params, moneyPkString, paramUpdaterPub,
   133  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   134  
   135  	// Send money to people from moneyPk
   136  	_, _, _ = _doBasicTransferWithViewFlush(
   137  		t, chain, db, params, moneyPkString, m0Pub,
   138  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   139  	_, _, _ = _doBasicTransferWithViewFlush(
   140  		t, chain, db, params, moneyPkString, m1Pub,
   141  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   142  	_, _, _ = _doBasicTransferWithViewFlush(
   143  		t, chain, db, params, moneyPkString, m2Pub,
   144  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   145  	_, _, _ = _doBasicTransferWithViewFlush(
   146  		t, chain, db, params, moneyPkString, m3Pub,
   147  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   148  	_, _, _ = _doBasicTransferWithViewFlush(
   149  		t, chain, db, params, moneyPkString, m4Pub,
   150  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   151  	_, _, _ = _doBasicTransferWithViewFlush(
   152  		t, chain, db, params, moneyPkString, m5Pub,
   153  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   154  	_, _, _ = _doBasicTransferWithViewFlush(
   155  		t, chain, db, params, moneyPkString, m6Pub,
   156  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   157  
   158  	m0StartNanos := _getBalance(t, chain, nil, m0Pub)
   159  	m1StartNanos := _getBalance(t, chain, nil, m1Pub)
   160  	m2StartNanos := _getBalance(t, chain, nil, m2Pub)
   161  	m3StartNanos := _getBalance(t, chain, nil, m3Pub)
   162  	m4StartNanos := _getBalance(t, chain, nil, m4Pub)
   163  	m5StartNanos := _getBalance(t, chain, nil, m5Pub)
   164  	m6StartNanos := _getBalance(t, chain, nil, m6Pub)
   165  
   166  	testUtxoOps := [][]*UtxoOperation{}
   167  	testTxns := []*MsgDeSoTxn{}
   168  	_checkTestData := func(
   169  		testData *_CreatorCoinTestData, message string, utxoView *UtxoView, mempool *DeSoMempool) {
   170  
   171  		// If we were instructed to skip these checks then skip them.
   172  		if testData.SkipChecks {
   173  			return
   174  		}
   175  
   176  		// If a mempool object is provided then just check balances and return
   177  		if mempool != nil {
   178  			// DeSo balances
   179  			if _getBalance(t, chain, mempool, m0Pub) != 6*NanosPerUnit && testData.m0DeSoBalance != 0 {
   180  				assert.Equalf(int64(testData.m0DeSoBalance),
   181  					int64(_getBalance(t, chain, mempool, m0Pub)), "MempoolIncrementalBalanceCheck: m0 DeSo balance: %v", message)
   182  			}
   183  			if _getBalance(t, chain, mempool, m1Pub) != 6*NanosPerUnit && testData.m1DeSoBalance != 0 {
   184  				assert.Equalf(int64(testData.m1DeSoBalance),
   185  					int64(_getBalance(t, chain, mempool, m1Pub)), "MempoolIncrementalBalanceCheck: m1 DeSo balance: %v", message)
   186  			}
   187  			if _getBalance(t, chain, mempool, m2Pub) != 6*NanosPerUnit && testData.m2DeSoBalance != 0 {
   188  				assert.Equalf(int64(testData.m2DeSoBalance),
   189  					int64(_getBalance(t, chain, mempool, m2Pub)), "MempoolIncrementalBalanceCheck: m2 DeSo balance: %v", message)
   190  			}
   191  			if _getBalance(t, chain, mempool, m3Pub) != 6*NanosPerUnit && testData.m3DeSoBalance != 0 {
   192  				assert.Equalf(int64(testData.m3DeSoBalance),
   193  					int64(_getBalance(t, chain, mempool, m3Pub)), "MempoolIncrementalBalanceCheck: m3 DeSo balance: %v", message)
   194  			}
   195  			if _getBalance(t, chain, mempool, m4Pub) != 6*NanosPerUnit && testData.m4DeSoBalance != 0 {
   196  				assert.Equalf(int64(testData.m4DeSoBalance),
   197  					int64(_getBalance(t, chain, mempool, m4Pub)), "MempoolIncrementalBalanceCheck: m4 DeSo balance: %v", message)
   198  			}
   199  			if _getBalance(t, chain, mempool, m5Pub) != 6*NanosPerUnit && testData.m5DeSoBalance != 0 {
   200  				assert.Equalf(int64(testData.m5DeSoBalance),
   201  					int64(_getBalance(t, chain, mempool, m5Pub)), "MempoolIncrementalBalanceCheck: m5 DeSo balance: %v", message)
   202  			}
   203  			if _getBalance(t, chain, mempool, m6Pub) != 6*NanosPerUnit && testData.m6DeSoBalance != 0 {
   204  				assert.Equalf(int64(testData.m6DeSoBalance),
   205  					int64(_getBalance(t, chain, mempool, m6Pub)), "MempoolIncrementalBalanceCheck: m6 DeSo balance: %v", message)
   206  			}
   207  
   208  			return
   209  		}
   210  
   211  		// If no UtxoView is passed, use a new one to run our checks.
   212  		if utxoView == nil {
   213  			var err error
   214  			utxoView, err = NewUtxoView(db, params, nil)
   215  			require.NoError(err)
   216  		}
   217  
   218  		// Profile fields
   219  		creatorPkBytes, _, _ := Base58CheckDecode(testData.ProfilePublicKeyBase58Check)
   220  		creatorProfile := utxoView.GetProfileEntryForPublicKey(creatorPkBytes)
   221  		require.NotNil(creatorProfile)
   222  
   223  		assert.Equalf(int64(testData.CoinsInCirculationNanos),
   224  			int64(creatorProfile.CoinsInCirculationNanos), "CoinsInCirculationNanos: %v", message)
   225  		assert.Equalf(int64(testData.DeSoLockedNanos),
   226  			int64(creatorProfile.DeSoLockedNanos), "DeSoLockedNanos: %v", message)
   227  		assert.Equalf(int64(testData.CoinWatermarkNanos),
   228  			int64(creatorProfile.CoinWatermarkNanos), "CoinWatermarkNanos: %v", message)
   229  
   230  		// Coin balances, also used for figuring out how many holders hold a creator.
   231  		// m0
   232  		actualNumberOfHolders := uint64(0)
   233  		m0BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m0PkBytes, creatorPkBytes)
   234  		if m0BalanceEntry != nil && !m0BalanceEntry.isDeleted {
   235  			assert.Equalf(int64(testData.m0CCBalance),
   236  				int64(m0BalanceEntry.BalanceNanos), "m0CCBalance: %v", message)
   237  			if m0BalanceEntry.BalanceNanos > 0 {
   238  				actualNumberOfHolders += 1
   239  			}
   240  			assert.Equal(testData.m0HasPurchased, m0BalanceEntry.HasPurchased)
   241  		} else {
   242  			assert.Equalf(int64(testData.m0CCBalance),
   243  				int64(0), "m0CCBalance: %v", message)
   244  			assert.Equal(testData.m0HasPurchased, false)
   245  		}
   246  		// m1
   247  		m1BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m1PkBytes, creatorPkBytes)
   248  		if m1BalanceEntry != nil && !m1BalanceEntry.isDeleted {
   249  			assert.Equalf(int64(testData.m1CCBalance),
   250  				int64(m1BalanceEntry.BalanceNanos), "m1CCBalance: %v", message)
   251  			if m1BalanceEntry.BalanceNanos > 0 {
   252  				actualNumberOfHolders += 1
   253  			}
   254  			assert.Equal(testData.m1HasPurchased, m1BalanceEntry.HasPurchased)
   255  		} else {
   256  			assert.Equalf(int64(testData.m1CCBalance),
   257  				int64(0), "m1CCBalance: %v", message)
   258  			assert.Equal(testData.m1HasPurchased, false)
   259  		}
   260  		// m2
   261  		m2BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m2PkBytes, creatorPkBytes)
   262  		if m2BalanceEntry != nil && !m2BalanceEntry.isDeleted {
   263  			assert.Equalf(int64(testData.m2CCBalance),
   264  				int64(m2BalanceEntry.BalanceNanos), "%v", message)
   265  			if m2BalanceEntry.BalanceNanos > 0 {
   266  				actualNumberOfHolders += 1
   267  			}
   268  			assert.Equal(testData.m2HasPurchased, m2BalanceEntry.HasPurchased)
   269  		} else {
   270  			assert.Equalf(int64(testData.m2CCBalance),
   271  				int64(0), "m2CCBalance: %v", message)
   272  			assert.Equal(testData.m2HasPurchased, false)
   273  		}
   274  		// m3
   275  		m3BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m3PkBytes, creatorPkBytes)
   276  		if m3BalanceEntry != nil && !m3BalanceEntry.isDeleted {
   277  			assert.Equalf(int64(testData.m3CCBalance),
   278  				int64(m3BalanceEntry.BalanceNanos), "%v", message)
   279  			if m3BalanceEntry.BalanceNanos > 0 {
   280  				actualNumberOfHolders += 1
   281  			}
   282  			assert.Equal(testData.m3HasPurchased, m3BalanceEntry.HasPurchased)
   283  		} else {
   284  			assert.Equalf(int64(testData.m3CCBalance),
   285  				int64(0), "m3CCBalance: %v", message)
   286  			assert.Equal(testData.m3HasPurchased, false)
   287  		}
   288  		// m4
   289  		m4BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m4PkBytes, creatorPkBytes)
   290  		if m4BalanceEntry != nil && !m4BalanceEntry.isDeleted {
   291  			assert.Equalf(int64(testData.m4CCBalance),
   292  				int64(m4BalanceEntry.BalanceNanos), "%v", message)
   293  			if m4BalanceEntry.BalanceNanos > 0 {
   294  				actualNumberOfHolders += 1
   295  			}
   296  			assert.Equal(testData.m4HasPurchased, m4BalanceEntry.HasPurchased)
   297  		} else {
   298  			assert.Equalf(int64(testData.m4CCBalance),
   299  				int64(0), "m4CCBalance: %v", message)
   300  			assert.Equal(testData.m4HasPurchased, false)
   301  		}
   302  		// m5
   303  		m5BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m5PkBytes, creatorPkBytes)
   304  		if m5BalanceEntry != nil && !m5BalanceEntry.isDeleted {
   305  			assert.Equalf(int64(testData.m5CCBalance),
   306  				int64(m5BalanceEntry.BalanceNanos), "%v", message)
   307  			if m5BalanceEntry.BalanceNanos > 0 {
   308  				actualNumberOfHolders += 1
   309  			}
   310  			assert.Equal(testData.m5HasPurchased, m5BalanceEntry.HasPurchased)
   311  		} else {
   312  			assert.Equalf(int64(testData.m5CCBalance),
   313  				int64(0), "m5CCBalance: %v", message)
   314  			assert.Equal(testData.m5HasPurchased, false)
   315  		}
   316  		// m6
   317  		m6BalanceEntry, _, _ := utxoView.GetBalanceEntryForHODLerPubKeyAndCreatorPubKey(m6PkBytes, creatorPkBytes)
   318  		if m6BalanceEntry != nil && !m6BalanceEntry.isDeleted {
   319  			assert.Equalf(int64(testData.m6CCBalance),
   320  				int64(m6BalanceEntry.BalanceNanos), "%v", message)
   321  			if m6BalanceEntry.BalanceNanos > 0 {
   322  				actualNumberOfHolders += 1
   323  			}
   324  			assert.Equal(testData.m6HasPurchased, m6BalanceEntry.HasPurchased)
   325  		} else {
   326  			assert.Equalf(int64(testData.m6CCBalance),
   327  				int64(0), "m6CCBalance: %v", message)
   328  			assert.Equal(testData.m6HasPurchased, false)
   329  		}
   330  
   331  		// creatorNumberOfHolders must equal creatorProfile.NumberOfHolders
   332  		assert.Equalf(actualNumberOfHolders, creatorProfile.NumberOfHolders,
   333  			"Actual number of creators != creatorProfile.NumberOfHolders: %v", message)
   334  
   335  		// Coins in m0+m1+m2+m3+m4+m5+m6 must equal the circulating supply
   336  		assert.Equalf(
   337  			int64(testData.m0CCBalance+testData.m1CCBalance+testData.m2CCBalance+testData.m3CCBalance+
   338  				testData.m4CCBalance+testData.m5CCBalance+testData.m6CCBalance),
   339  			int64(creatorProfile.CoinsInCirculationNanos),
   340  			"m0+m1+m2+m3+m4+m5+m6 != CoinsInCirculationNanos: %v", message)
   341  
   342  		// DeSo balances
   343  		if _getBalanceWithView(t, utxoView, m0Pub) != 6*NanosPerUnit && testData.m0DeSoBalance != 0 {
   344  			assert.Equalf(int64(testData.m0DeSoBalance),
   345  				int64(_getBalanceWithView(t, utxoView, m0Pub)), "m0 DeSo balance: %v", message)
   346  		}
   347  		if _getBalanceWithView(t, utxoView, m1Pub) != 6*NanosPerUnit && testData.m1DeSoBalance != 0 {
   348  			assert.Equalf(int64(testData.m1DeSoBalance),
   349  				int64(_getBalanceWithView(t, utxoView, m1Pub)), "m1 DeSo balance: %v", message)
   350  		}
   351  		if _getBalanceWithView(t, utxoView, m2Pub) != 6*NanosPerUnit && testData.m2DeSoBalance != 0 {
   352  			assert.Equalf(int64(testData.m2DeSoBalance),
   353  				int64(_getBalanceWithView(t, utxoView, m2Pub)), "m2 DeSo balance: %v", message)
   354  		}
   355  		if _getBalanceWithView(t, utxoView, m3Pub) != 6*NanosPerUnit && testData.m3DeSoBalance != 0 {
   356  			assert.Equalf(int64(testData.m3DeSoBalance),
   357  				int64(_getBalanceWithView(t, utxoView, m3Pub)), "m3 DeSo balance: %v", message)
   358  		}
   359  		if _getBalanceWithView(t, utxoView, m4Pub) != 6*NanosPerUnit && testData.m4DeSoBalance != 0 {
   360  			assert.Equalf(int64(testData.m4DeSoBalance),
   361  				int64(_getBalanceWithView(t, utxoView, m4Pub)), "m4 DeSo balance: %v", message)
   362  		}
   363  		if _getBalanceWithView(t, utxoView, m5Pub) != 6*NanosPerUnit && testData.m5DeSoBalance != 0 {
   364  			assert.Equalf(int64(testData.m5DeSoBalance),
   365  				int64(_getBalanceWithView(t, utxoView, m5Pub)), "m5 DeSo balance: %v", message)
   366  		}
   367  		if _getBalanceWithView(t, utxoView, m6Pub) != 6*NanosPerUnit && testData.m6DeSoBalance != 0 {
   368  			assert.Equalf(int64(testData.m6DeSoBalance),
   369  				int64(_getBalanceWithView(t, utxoView, m6Pub)), "m6 DeSo balance: %v", message)
   370  		}
   371  
   372  		for ii, profilePubStr := range testData.ProfilesToCheckPublicKeysBase58Check {
   373  			// Look up the profile for the public key.
   374  			profilePkBytes, _, _ := Base58CheckDecode(profilePubStr)
   375  			profileEntry := utxoView.GetProfileEntryForPublicKey(profilePkBytes)
   376  			if testData.ProfilesToCheckUsernames[ii] == "" {
   377  				if profileEntry != nil && !profileEntry.isDeleted {
   378  					require.Fail("Profile for pub key %v should not exist but does: index %v: %v", profilePubStr, ii, message)
   379  				}
   380  				continue
   381  			} else {
   382  				require.NotNil(profileEntry, "Profile for pub key %v does not exist: index %v: %v", profilePubStr, ii, message)
   383  			}
   384  			require.Equalf(profilePkBytes, profileEntry.PublicKey, "Profile public keys don't match: index %v: %v", ii, message)
   385  			require.Equalf(string(profileEntry.Username), testData.ProfilesToCheckUsernames[ii], "Profile usernames don't match: index %v: %v", ii, message)
   386  			require.Equalf(string(profileEntry.Description), testData.ProfilesToCheckDescriptions[ii], "Profile descripptions don't match: index %v: %v", ii, message)
   387  			require.Equalf(string(profileEntry.ProfilePic), testData.ProfilesToCheckProfilePic[ii], "Profile profile pics don't match: index %v: %v", ii, message)
   388  		}
   389  
   390  		for ii, userPubStr := range testData.FollowPublicKeysToCheck {
   391  			// Look up the profile for the public key.
   392  			userPkBytes, _, _ := Base58CheckDecode(userPubStr)
   393  
   394  			userIsFollowing := testData.FollowPublicKeysUserIsFollowing[ii]
   395  			followingUser := testData.FollowPublicKeysFollowingThisUser[ii]
   396  
   397  			// Look up the public keys that are following this user.
   398  			{
   399  				followEntries, err := utxoView.GetFollowEntriesForPublicKey(
   400  					userPkBytes, true /*followingPublicKey*/)
   401  				require.NoError(err)
   402  
   403  				require.Equal(len(followEntries), len(followingUser))
   404  
   405  				for _, followEntry := range followEntries {
   406  					followPk := utxoView.GetPublicKeyForPKID(followEntry.FollowerPKID)
   407  					if _, exists := followingUser[PkToString(followPk, params)]; !exists {
   408  						require.Fail(fmt.Sprintf("Pub key %v should be following user %v but is not: %v %v",
   409  							PkToString(followPk, params), userPubStr, ii, message))
   410  					}
   411  				}
   412  			}
   413  			// Look up the public keys this user is following
   414  			{
   415  				followEntries, err := utxoView.GetFollowEntriesForPublicKey(
   416  					userPkBytes, false /*followingPublicKey*/)
   417  				require.NoError(err)
   418  
   419  				require.Equal(len(followEntries), len(userIsFollowing))
   420  
   421  				for _, followEntry := range followEntries {
   422  					followPk := utxoView.GetPublicKeyForPKID(followEntry.FollowedPKID)
   423  					if _, exists := userIsFollowing[PkToString(followPk, params)]; !exists {
   424  						require.Fail(fmt.Sprintf("Pub key %v should be in the users this one is following %v but is not: %v %v",
   425  							PkToString(followPk, params), userPubStr, ii, message))
   426  					}
   427  				}
   428  			}
   429  		}
   430  	}
   431  
   432  	postHashes := []*BlockHash{}
   433  	for testIndex, testData := range creatorCoinTests {
   434  		fmt.Printf("Applying test index: %v\n", testIndex)
   435  
   436  		// If this is a profile swap, then execute that.
   437  		var utxoOps []*UtxoOperation
   438  		var txn *MsgDeSoTxn
   439  		var err error
   440  		if testData.TxnType == TxnTypeSwapIdentity {
   441  			utxoOps, txn, _, err = _swapIdentity(
   442  				t, chain, db, params, feeRateNanosPerKB,
   443  				paramUpdaterPub,
   444  				paramUpdaterPriv,
   445  				testData.FromPublicKey, testData.ToPublicKey)
   446  			require.NoError(err)
   447  		} else if testData.TxnType == TxnTypeUpdateProfile {
   448  			// Create a profile using the testData params
   449  			profilePkBytes, _, _ := Base58CheckDecode(testData.ProfilePublicKeyBase58Check)
   450  			utxoOps, txn, _, err = _updateProfile(
   451  				t, chain, db, params,
   452  				feeRateNanosPerKB /*feerate*/, testData.UpdaterPublicKeyBase58Check,
   453  				testData.UpdaterPrivateKeyBase58Check, profilePkBytes, testData.ProfileUsername,
   454  				testData.ProfileDescription, testData.ProfilePic,
   455  				testData.ProfileCreatorBasisPoints, /*CreatorBasisPoints*/
   456  				12500 /*stakeMultipleBasisPoints*/, testData.ProfileIsHidden /*isHidden*/)
   457  			require.NoError(err)
   458  		} else if testData.TxnType == TxnTypeFollow {
   459  			utxoOps, txn, _, err = _doFollowTxn(
   460  				t, chain, db, params, feeRateNanosPerKB /*feeRateNanosPerKB*/, testData.UpdaterPublicKeyBase58Check,
   461  				PkToString(testData.FollowedPublicKey, params),
   462  				testData.UpdaterPrivateKeyBase58Check, testData.IsUnfollow /*isUnfollow*/)
   463  			require.NoError(err)
   464  		} else if testData.TxnType == TxnTypeSubmitPost {
   465  
   466  			var postHashToModify []byte
   467  			if testData.PostHashToModifyIndex >= 0 {
   468  				postHashToModify = postHashes[testData.PostHashToModifyIndex][:]
   469  			}
   470  			var parentPostHash []byte
   471  			if testData.ParentPostHashIndex >= 0 {
   472  				parentPostHash = postHashes[testData.ParentPostHashIndex][:]
   473  			}
   474  
   475  			utxoOps, txn, _, err = _doSubmitPostTxn(
   476  				t, chain, db, params, feeRateNanosPerKB,
   477  				testData.UpdaterPublicKeyBase58Check, testData.UpdaterPrivateKeyBase58Check,
   478  				postHashToModify,
   479  				parentPostHash,
   480  				testData.SubmitPostBody,
   481  				make(map[string][]byte),
   482  				testData.PostIsHidden)
   483  			require.NoError(err)
   484  
   485  			// If this transaction was not modifying an existing post then
   486  			// add its post hash to the list.
   487  			if len(postHashToModify) == 0 {
   488  				postHashes = append(postHashes, txn.Hash())
   489  			}
   490  
   491  		} else if testData.TxnType == TxnTypeCreatorCoinTransfer {
   492  			var diamondPostHash *BlockHash
   493  			if testData.DiamondLevel > 0 {
   494  				diamondPostHash = postHashes[testData.DiamondPostHashIndex]
   495  			}
   496  			// If we have a DiamondPostHash then do a diamond txn
   497  			if diamondPostHash != nil {
   498  				utxoOps, txn, _, err = _doCreatorCoinTransferTxnWithDiamonds(
   499  					t, chain, db, params, feeRateNanosPerKB,
   500  					testData.UpdaterPublicKeyBase58Check, testData.UpdaterPrivateKeyBase58Check,
   501  					testData.ReceiverPublicKeyBase58Check,
   502  					diamondPostHash,
   503  					testData.DiamondLevel)
   504  				require.NoError(err)
   505  			} else {
   506  				// Apply the txn according to the test spec
   507  				utxoOps, txn, _, err = _doCreatorCoinTransferTxn(
   508  					t, chain, db, params, feeRateNanosPerKB,
   509  					testData.UpdaterPublicKeyBase58Check, testData.UpdaterPrivateKeyBase58Check,
   510  					testData.ProfilePublicKeyBase58Check,
   511  					testData.ReceiverPublicKeyBase58Check,
   512  					testData.CreatorCoinToTransferNanos)
   513  				require.NoError(err)
   514  			}
   515  
   516  		} else {
   517  			// When TxnType is 0 aka "unset," we assume we're doing a CreatorCoin txn.
   518  
   519  			// Apply the txn according to the test spec
   520  			utxoOps, txn, _, err = _creatorCoinTxn(
   521  				t, chain, db, params, feeRateNanosPerKB,
   522  				testData.UpdaterPublicKeyBase58Check, testData.UpdaterPrivateKeyBase58Check, /*updater*/
   523  				testData.ProfilePublicKeyBase58Check, /*profile*/
   524  				testData.OperationType,               /*buy/sell*/
   525  				testData.DeSoToSellNanos,             /*DeSoToSellNanos*/
   526  				testData.CreatorCoinToSellNanos,      /*CreatorCoinToSellNanos*/
   527  				testData.DeSoToAddNanos,              /*DeSoToAddNanos*/
   528  				testData.MinDeSoExpectedNanos,        /*MinDeSoExpectedNanos*/
   529  				testData.MinCreatorCoinExpectedNanos /*MinCreatorCoinExpectedNanos*/)
   530  			require.NoError(err)
   531  		}
   532  
   533  		// Append the txn we just created to our list
   534  		testTxns = append(testTxns, txn)
   535  		testUtxoOps = append(testUtxoOps, utxoOps)
   536  
   537  		// Check the txn according to the test spec.
   538  		_checkTestData(testData, fmt.Sprintf("SimpleConnect: Index: %v", testIndex), nil, nil)
   539  	}
   540  
   541  	// The sum of all the balances shouldn't exceed what we started with.
   542  	assert.Less(
   543  		int64(_getBalance(t, chain, nil, m0Pub)+_getBalance(t, chain, nil, m1Pub)+
   544  			_getBalance(t, chain, nil, m2Pub)+_getBalance(t, chain, nil, m3Pub)+
   545  			_getBalance(t, chain, nil, m4Pub)+_getBalance(t, chain, nil, m5Pub)+
   546  			_getBalance(t, chain, nil, m6Pub)),
   547  		int64(m0StartNanos+m1StartNanos+m2StartNanos+m3StartNanos+m4StartNanos+m5StartNanos+m6StartNanos))
   548  
   549  	// Disconnect each txn and rerun the checks in the reverse direction
   550  	for iterIndex := range creatorCoinTests {
   551  		testIndex := len(creatorCoinTests) - 1 - iterIndex
   552  		testData := creatorCoinTests[testIndex]
   553  		currentTxn := testTxns[testIndex]
   554  		currentUtxoOps := testUtxoOps[testIndex]
   555  
   556  		// Check that the state lines up with the test data
   557  		fmt.Printf("Running checks before disconnecting test index: %v\n", testIndex)
   558  		_checkTestData(testData, fmt.Sprintf("SimpleDisconnect: Index: %v", testIndex), nil, nil)
   559  
   560  		// Disconnect the transaction
   561  		utxoView, err := NewUtxoView(db, params, nil)
   562  		require.NoError(err)
   563  		blockHeight := chain.blockTip().Height + 1
   564  		fmt.Printf("Disconnecting test index: %v\n", testIndex)
   565  		require.NoError(utxoView.DisconnectTransaction(
   566  			currentTxn, currentTxn.Hash(), currentUtxoOps, blockHeight))
   567  		fmt.Printf("Disconnected test index: %v\n", testIndex)
   568  		require.NoErrorf(utxoView.FlushToDb(), "SimpleDisconnect: Index: %v", testIndex)
   569  	}
   570  
   571  	// Verify the DeSo balances are back to where they started after disconnecting all the txns.
   572  	assert.Equalf(int64(m0StartNanos),
   573  		int64(_getBalance(t, chain, nil, m0Pub)), "m0 DeSo balance after SimpleDisconnect is incorrect")
   574  	assert.Equalf(int64(m1StartNanos),
   575  		int64(_getBalance(t, chain, nil, m1Pub)), "m1 DeSo balance after SimpleDisconnect is incorrect")
   576  	assert.Equalf(int64(m2StartNanos),
   577  		int64(_getBalance(t, chain, nil, m2Pub)), "m2 DeSo balance after SimpleDisconnect is incorrect")
   578  	assert.Equalf(int64(m3StartNanos),
   579  		int64(_getBalance(t, chain, nil, m3Pub)), "m3 DeSo balance after SimpleDisconnect is incorrect")
   580  	assert.Equalf(int64(m4StartNanos),
   581  		int64(_getBalance(t, chain, nil, m4Pub)), "m4 DeSo balance after SimpleDisconnect is incorrect")
   582  	assert.Equalf(int64(m5StartNanos),
   583  		int64(_getBalance(t, chain, nil, m5Pub)), "m5 DeSo balance after SimpleDisconnect is incorrect")
   584  	assert.Equalf(int64(m6StartNanos),
   585  		int64(_getBalance(t, chain, nil, m6Pub)), "m6 DeSo balance after SimpleDisconnect is incorrect")
   586  
   587  	// Connect all the txns to a single UtxoView without flushing
   588  	{
   589  		// Create a new UtxoView to check on the state of things
   590  		utxoView, err := NewUtxoView(db, params, nil)
   591  		require.NoError(err)
   592  		for testIndex, testData := range creatorCoinTests {
   593  			fmt.Printf("Applying test index: %v\n", testIndex)
   594  			txn := testTxns[testIndex]
   595  			blockHeight := chain.blockTip().Height + 1
   596  			txnSize := getTxnSize(*txn)
   597  			_, _, _, _, err :=
   598  				utxoView.ConnectTransaction(
   599  					txn, txn.Hash(), txnSize, blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
   600  			require.NoError(err)
   601  			_checkTestData(testData, fmt.Sprintf("SimpleConnect: Index: %v", testIndex), utxoView, nil)
   602  		}
   603  
   604  		// Now flush at the end.
   605  		require.NoError(utxoView.FlushToDb())
   606  
   607  		// Check that the state matches the final testData.
   608  		testIndex := len(creatorCoinTests) - 1
   609  		testData := creatorCoinTests[testIndex]
   610  		_checkTestData(testData, fmt.Sprintf("OnebigFlush: %v", testIndex), nil, nil)
   611  	}
   612  
   613  	// Disconnect all the txns on a single view and flush at the end
   614  	{
   615  		// Create a new UtxoView to check on the state of things
   616  		utxoView, err := NewUtxoView(db, params, nil)
   617  		require.NoError(err)
   618  		blockHeight := chain.blockTip().Height + 1
   619  		for iterIndex := range creatorCoinTests {
   620  			testIndex := len(creatorCoinTests) - 1 - iterIndex
   621  			fmt.Printf("Disconnecting test index: %v\n", testIndex)
   622  			txn := testTxns[testIndex]
   623  			require.NoError(utxoView.DisconnectTransaction(
   624  				txn, txn.Hash(), testUtxoOps[testIndex], blockHeight))
   625  
   626  			// Check that the testData lines up
   627  			if testIndex > 0 {
   628  				testData := creatorCoinTests[testIndex-1]
   629  				_checkTestData(testData, fmt.Sprintf("OneBigFlush: %v", testIndex), utxoView, nil)
   630  			}
   631  		}
   632  
   633  		// Now flush at the end.
   634  		require.NoError(utxoView.FlushToDb())
   635  
   636  		// Verify the DeSo balances are back to where they started after disconnecting all the txns.
   637  		assert.Equalf(int64(m0StartNanos),
   638  			int64(_getBalance(t, chain, nil, m0Pub)), "m0 DeSo balance after BatchDisconnect is incorrect")
   639  		assert.Equalf(int64(m1StartNanos),
   640  			int64(_getBalance(t, chain, nil, m1Pub)), "m1 DeSo balance after BatchDisconnect is incorrect")
   641  		assert.Equalf(int64(m2StartNanos),
   642  			int64(_getBalance(t, chain, nil, m2Pub)), "m2 DeSo balance after BatchDisconnect is incorrect")
   643  		assert.Equalf(int64(m3StartNanos),
   644  			int64(_getBalance(t, chain, nil, m3Pub)), "m3 DeSo balance after BatchDisconnect is incorrect")
   645  		assert.Equalf(int64(m4StartNanos),
   646  			int64(_getBalance(t, chain, nil, m4Pub)), "m4 DeSo balance after BatchDisconnect is incorrect")
   647  		assert.Equalf(int64(m5StartNanos),
   648  			int64(_getBalance(t, chain, nil, m5Pub)), "m5 DeSo balance after BatchDisconnect is incorrect")
   649  		assert.Equalf(int64(m6StartNanos),
   650  			int64(_getBalance(t, chain, nil, m6Pub)), "m6 DeSo balance after BatchDisconnect is incorrect")
   651  	}
   652  
   653  	// Running all the transactions through the mempool should work and result
   654  	// in all of them being added.
   655  	{
   656  		for ii, currentTxn := range testTxns {
   657  			mempoolTxsAdded, err := mempool.processTransaction(
   658  				currentTxn, true /*allowUnconnectedTxn*/, true /*rateLimit*/, 0, /*peerID*/
   659  				true /*verifySignatures*/)
   660  			require.NoErrorf(err, "mempool index %v", ii)
   661  			require.Equal(1, len(mempoolTxsAdded))
   662  
   663  			// This will check the balances according to the mempool
   664  			_checkTestData(creatorCoinTests[ii], fmt.Sprintf("MempoolIncrementalBalances: %v", ii), nil, mempool)
   665  		}
   666  	}
   667  
   668  	// Remove all the transactions from the mempool.
   669  	for _, burnTxn := range testTxns {
   670  		mempool.inefficientRemoveTransaction(burnTxn)
   671  	}
   672  
   673  	// The balances should be reset after removing transactions from the mempool.
   674  	assert.Equalf(int64(m0StartNanos),
   675  		int64(_getBalance(t, chain, nil, m0Pub)), "m0 DeSo balance after BatchDisconnect is incorrect")
   676  	assert.Equalf(int64(m1StartNanos),
   677  		int64(_getBalance(t, chain, nil, m1Pub)), "m1 DeSo balance after BatchDisconnect is incorrect")
   678  	assert.Equalf(int64(m2StartNanos),
   679  		int64(_getBalance(t, chain, nil, m2Pub)), "m2 DeSo balance after BatchDisconnect is incorrect")
   680  	assert.Equalf(int64(m3StartNanos),
   681  		int64(_getBalance(t, chain, nil, m3Pub)), "m3 DeSo balance after BatchDisconnect is incorrect")
   682  	assert.Equalf(int64(m4StartNanos),
   683  		int64(_getBalance(t, chain, nil, m4Pub)), "m4 DeSo balance after BatchDisconnect is incorrect")
   684  	assert.Equalf(int64(m5StartNanos),
   685  		int64(_getBalance(t, chain, nil, m5Pub)), "m5 DeSo balance after BatchDisconnect is incorrect")
   686  	assert.Equalf(int64(m6StartNanos),
   687  		int64(_getBalance(t, chain, nil, m6Pub)), "m6 DeSo balance after BatchDisconnect is incorrect")
   688  
   689  	// Re-add all of the transactions to the mempool so we can mine them into a block.
   690  	{
   691  		for _, burnTxn := range testTxns {
   692  			mempoolTxsAdded, err := mempool.processTransaction(
   693  				burnTxn, true /*allowUnconnectedTxn*/, true /*rateLimit*/, 0, /*peerID*/
   694  				true /*verifySignatures*/)
   695  			require.NoError(err)
   696  			require.Equal(1, len(mempoolTxsAdded))
   697  		}
   698  	}
   699  
   700  	// Mine a block with all the mempool transactions.
   701  	//
   702  	// All the txns should be in the mempool already so mining a block should put
   703  	// all those transactions in it. Note we need to mine two blocks since the first
   704  	// one just makes the DeSo chain time-current.
   705  	finalBlock1, err := miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool)
   706  	require.NoError(err)
   707  	_ = finalBlock1
   708  	finalBlock2, err := miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool)
   709  	require.NoError(err)
   710  	require.Equal(0, len(mempool.poolMap))
   711  
   712  	// Add one for the block reward. Now we have a meaty block.
   713  	require.Equal(len(finalBlock1.Txns), 1)
   714  	require.Equal(len(finalBlock2.Txns), len(creatorCoinTests)+1)
   715  
   716  	// The balances after mining the block should match the last testData
   717  	{
   718  		// Check that the state matches the final testData.
   719  		testIndex := len(creatorCoinTests) - 1
   720  		testData := creatorCoinTests[testIndex]
   721  		// DeSo balances
   722  		if _getBalance(t, chain, nil, m0Pub) != 6*NanosPerUnit && testData.m0DeSoBalance != 0 {
   723  			assert.Equalf(int64(testData.m0DeSoBalance),
   724  				int64(_getBalance(t, chain, nil, m0Pub)), "BlockConnect: m0 DeSo balance: %v", testIndex)
   725  		}
   726  		if _getBalance(t, chain, nil, m1Pub) != 6*NanosPerUnit && testData.m1DeSoBalance != 0 {
   727  			assert.Equalf(int64(testData.m1DeSoBalance),
   728  				int64(_getBalance(t, chain, nil, m1Pub)), "BlockConnect: m1 DeSo balance: %v", testIndex)
   729  		}
   730  		if _getBalance(t, chain, nil, m2Pub) != 6*NanosPerUnit && testData.m2DeSoBalance != 0 {
   731  			assert.Equalf(int64(testData.m2DeSoBalance),
   732  				int64(_getBalance(t, chain, nil, m2Pub)), "BlockConnect: m2 DeSo balance: %v", testIndex)
   733  		}
   734  		if _getBalance(t, chain, nil, m3Pub) != 6*NanosPerUnit && testData.m3DeSoBalance != 0 {
   735  			assert.Equalf(int64(testData.m3DeSoBalance),
   736  				int64(_getBalance(t, chain, nil, m3Pub)), "BlockConnect: m3 DeSo balance: %v", testIndex)
   737  		}
   738  		if _getBalance(t, chain, nil, m4Pub) != 6*NanosPerUnit && testData.m4DeSoBalance != 0 {
   739  			assert.Equalf(int64(testData.m4DeSoBalance),
   740  				int64(_getBalance(t, chain, nil, m4Pub)), "BlockConnect: m4 DeSo balance: %v", testIndex)
   741  		}
   742  		if _getBalance(t, chain, nil, m5Pub) != 6*NanosPerUnit && testData.m5DeSoBalance != 0 {
   743  			assert.Equalf(int64(testData.m5DeSoBalance),
   744  				int64(_getBalance(t, chain, nil, m5Pub)), "BlockConnect: m5 DeSo balance: %v", testIndex)
   745  		}
   746  		if _getBalance(t, chain, nil, m6Pub) != 6*NanosPerUnit && testData.m5DeSoBalance != 0 {
   747  			assert.Equalf(int64(testData.m6DeSoBalance),
   748  				int64(_getBalance(t, chain, nil, m6Pub)), "BlockConnect: m6 DeSo balance: %v", testIndex)
   749  		}
   750  
   751  	}
   752  
   753  	// Roll back the blocks and make sure we don't hit any errors.
   754  	disconnectSingleBlock := func(blockToDisconnect *MsgDeSoBlock, utxoView *UtxoView) {
   755  		// Fetch the utxo operations for the block we're detaching. We need these
   756  		// in order to be able to detach the block.
   757  		hash, err := blockToDisconnect.Header.Hash()
   758  		require.NoError(err)
   759  		utxoOps, err := GetUtxoOperationsForBlock(db, hash)
   760  		require.NoError(err)
   761  
   762  		// Compute the hashes for all the transactions.
   763  		txHashes, err := ComputeTransactionHashes(blockToDisconnect.Txns)
   764  		require.NoError(err)
   765  		require.NoError(utxoView.DisconnectBlock(blockToDisconnect, txHashes, utxoOps))
   766  	}
   767  	{
   768  		utxoView, err := NewUtxoView(db, params, nil)
   769  		require.NoError(err)
   770  
   771  		disconnectSingleBlock(finalBlock2, utxoView)
   772  		disconnectSingleBlock(finalBlock1, utxoView)
   773  
   774  		// Flushing the view after applying and rolling back should work.
   775  		require.NoError(utxoView.FlushToDb())
   776  	}
   777  
   778  	// The DeSo balances should line up with what they were initially after
   779  	// disconnecting the blocks.
   780  	assert.Equalf(int64(m0StartNanos),
   781  		int64(_getBalance(t, chain, nil, m0Pub)), "m0 DeSo balance after BlockDisconnect is incorrect")
   782  	assert.Equalf(int64(m1StartNanos),
   783  		int64(_getBalance(t, chain, nil, m1Pub)), "m1 DeSo balance after BlockDisconnect is incorrect")
   784  	assert.Equalf(int64(m2StartNanos),
   785  		int64(_getBalance(t, chain, nil, m2Pub)), "m2 DeSo balance after BlockDisconnect is incorrect")
   786  	assert.Equalf(int64(m3StartNanos),
   787  		int64(_getBalance(t, chain, nil, m3Pub)), "m3 DeSo balance after BlockDisconnect is incorrect")
   788  	assert.Equalf(int64(m5StartNanos),
   789  		int64(_getBalance(t, chain, nil, m5Pub)), "m5 DeSo balance after BlockDisconnect is incorrect")
   790  	assert.Equalf(int64(m6StartNanos),
   791  		int64(_getBalance(t, chain, nil, m6Pub)), "m6 DeSo balance after BlockDisconnect is incorrect")
   792  }
   793  
   794  func TestCreatorCoinWithDiamonds(t *testing.T) {
   795  	// Set up a blockchain
   796  	assert := assert.New(t)
   797  	require := require.New(t)
   798  	_, _ = assert, require
   799  
   800  	creatorCoinTests := []*_CreatorCoinTestData{
   801  		// Create a profile for m0
   802  		{
   803  			TxnType:                      TxnTypeUpdateProfile,
   804  			UpdaterPublicKeyBase58Check:  m0Pub,
   805  			UpdaterPrivateKeyBase58Check: m0Priv,
   806  			ProfilePublicKeyBase58Check:  m0Pub,
   807  			ProfileUsername:              "m0",
   808  			ProfileDescription:           "i am m0",
   809  			ProfilePic:                   "m0 profile pic",
   810  			ProfileCreatorBasisPoints:    2500,
   811  			ProfileIsHidden:              false,
   812  
   813  			SkipChecks: true,
   814  		},
   815  		// Have m0 buy some of their own coin
   816  		{
   817  			// These are the transaction params
   818  			UpdaterPublicKeyBase58Check:  m0Pub,
   819  			UpdaterPrivateKeyBase58Check: m0Priv,
   820  			ProfilePublicKeyBase58Check:  m0Pub,
   821  			OperationType:                CreatorCoinOperationTypeBuy,
   822  			DeSoToSellNanos:              1271123456,
   823  			CreatorCoinToSellNanos:       0,
   824  			DeSoToAddNanos:               0,
   825  			MinDeSoExpectedNanos:         0,
   826  			MinCreatorCoinExpectedNanos:  0,
   827  
   828  			// These are the expectations
   829  			CoinsInCirculationNanos: 10832150315,
   830  			DeSoLockedNanos:         1270996343,
   831  			CoinWatermarkNanos:      10832150315,
   832  			m0CCBalance:             10832150315,
   833  			m0HasPurchased:          true,
   834  			m1CCBalance:             0,
   835  			m1HasPurchased:          false,
   836  			m2CCBalance:             0,
   837  			m2HasPurchased:          false,
   838  			m0DeSoBalance:           4728876540,
   839  			m1DeSoBalance:           6000000000,
   840  			m2DeSoBalance:           6000000000,
   841  		},
   842  		// Create a post for m0
   843  		{
   844  			TxnType:                      TxnTypeSubmitPost,
   845  			UpdaterPublicKeyBase58Check:  m0Pub,
   846  			UpdaterPrivateKeyBase58Check: m0Priv,
   847  
   848  			PostHashToModifyIndex: -1,
   849  			ParentPostHashIndex:   -1,
   850  			SubmitPostBody:        "this is a post for m0",
   851  			PostIsHidden:          false,
   852  
   853  			SkipChecks: true,
   854  		},
   855  		// Create a post from m1 that is a comment on m0
   856  		{
   857  			TxnType:                      TxnTypeSubmitPost,
   858  			UpdaterPublicKeyBase58Check:  m1Pub,
   859  			UpdaterPrivateKeyBase58Check: m1Priv,
   860  			PostHashToModifyIndex:        -1,
   861  			ParentPostHashIndex:          0,
   862  			SubmitPostBody:               "this is a comment for m1",
   863  			PostIsHidden:                 false,
   864  
   865  			SkipChecks: true,
   866  		},
   867  		// Create a post from m2 that is a comment on m0
   868  		{
   869  			TxnType:                      TxnTypeSubmitPost,
   870  			UpdaterPublicKeyBase58Check:  m2Pub,
   871  			UpdaterPrivateKeyBase58Check: m2Priv,
   872  			PostHashToModifyIndex:        -1,
   873  			ParentPostHashIndex:          0,
   874  			SubmitPostBody:               "this is a comment for m2",
   875  			PostIsHidden:                 false,
   876  
   877  			SkipChecks: true,
   878  		},
   879  		// Have m0 throw a diamond on m1's comment
   880  		{
   881  			TxnType: TxnTypeCreatorCoinTransfer,
   882  			// These are the transaction params
   883  			UpdaterPublicKeyBase58Check:  m0Pub,
   884  			UpdaterPrivateKeyBase58Check: m0Priv,
   885  			ReceiverPublicKeyBase58Check: m1Pub,
   886  			ProfilePublicKeyBase58Check:  m0Pub,
   887  			// This field is ignored when giving a diamond. It's computed
   888  			// by the functions called.
   889  			CreatorCoinToTransferNanos: 0,
   890  			DiamondPostHashIndex:       1,
   891  			DiamondLevel:               3,
   892  
   893  			// These are the expectations
   894  			CoinsInCirculationNanos: 10832150315,
   895  			DeSoLockedNanos:         1270996343,
   896  			CoinWatermarkNanos:      10832150315,
   897  			m0CCBalance:             10817255342,
   898  			m0HasPurchased:          true,
   899  			m1CCBalance:             14894973,
   900  			m1HasPurchased:          false,
   901  			m2CCBalance:             0,
   902  			m2HasPurchased:          false,
   903  			m0DeSoBalance:           4728876535,
   904  			m1DeSoBalance:           5999999998,
   905  			m2DeSoBalance:           5999999998,
   906  		},
   907  		// m0 upgrading the diamond level should work
   908  		{
   909  			TxnType: TxnTypeCreatorCoinTransfer,
   910  			// These are the transaction params
   911  			UpdaterPublicKeyBase58Check:  m0Pub,
   912  			UpdaterPrivateKeyBase58Check: m0Priv,
   913  			ReceiverPublicKeyBase58Check: m1Pub,
   914  			ProfilePublicKeyBase58Check:  m0Pub,
   915  			// This field is ignored when giving a diamond. It's computed
   916  			// by the functions called.
   917  			CreatorCoinToTransferNanos: 0,
   918  			DiamondPostHashIndex:       1,
   919  			DiamondLevel:               4,
   920  
   921  			// These are the expectations
   922  			CoinsInCirculationNanos: 10832150315,
   923  			DeSoLockedNanos:         1270996343,
   924  			CoinWatermarkNanos:      10832150315,
   925  			m0CCBalance:             10684919520,
   926  			m0HasPurchased:          true,
   927  			m1CCBalance:             147230795,
   928  			m1HasPurchased:          false,
   929  			m2CCBalance:             0,
   930  			m2HasPurchased:          false,
   931  			m0DeSoBalance:           4728876532,
   932  			m1DeSoBalance:           5999999998,
   933  			m2DeSoBalance:           5999999998,
   934  		},
   935  		// m0 giving diamond level 4 to m2 should result in the same
   936  		// CC balance for m2 as m1 has
   937  		{
   938  			TxnType: TxnTypeCreatorCoinTransfer,
   939  			// These are the transaction params
   940  			UpdaterPublicKeyBase58Check:  m0Pub,
   941  			UpdaterPrivateKeyBase58Check: m0Priv,
   942  			ReceiverPublicKeyBase58Check: m2Pub,
   943  			ProfilePublicKeyBase58Check:  m0Pub,
   944  			// This field is ignored when giving a diamond. It's computed
   945  			// by the functions called.
   946  			CreatorCoinToTransferNanos: 0,
   947  			DiamondPostHashIndex:       2,
   948  			DiamondLevel:               4,
   949  
   950  			// These are the expectations
   951  			CoinsInCirculationNanos: 10832150315,
   952  			DeSoLockedNanos:         1270996343,
   953  			CoinWatermarkNanos:      10832150315,
   954  			m0CCBalance:             10537688724,
   955  			m0HasPurchased:          true,
   956  			m1CCBalance:             147230795,
   957  			m1HasPurchased:          false,
   958  			m2CCBalance:             147230796,
   959  			m2HasPurchased:          false,
   960  			m0DeSoBalance:           4728876529,
   961  			m1DeSoBalance:           5999999998,
   962  			m2DeSoBalance:           5999999998,
   963  		},
   964  	}
   965  
   966  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
   967  }
   968  
   969  func TestCreatorCoinWithDiamondsFailureCases(t *testing.T) {
   970  	// Set up a blockchain
   971  	assert := assert.New(t)
   972  	require := require.New(t)
   973  	_, _ = assert, require
   974  
   975  	chain, params, db := NewLowDifficultyBlockchain()
   976  	mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/)
   977  	feeRateNanosPerKB := uint64(11)
   978  	_, _ = mempool, miner
   979  
   980  	// Create a paramUpdater for this test
   981  	params.ParamUpdaterPublicKeys[MakePkMapKey(paramUpdaterPkBytes)] = true
   982  
   983  	// Give paramUpdater some mony
   984  	_, _, _ = _doBasicTransferWithViewFlush(
   985  		t, chain, db, params, moneyPkString, paramUpdaterPub,
   986  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   987  
   988  	// Send money to people from moneyPk
   989  	_, _, _ = _doBasicTransferWithViewFlush(
   990  		t, chain, db, params, moneyPkString, m0Pub,
   991  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   992  	_, _, _ = _doBasicTransferWithViewFlush(
   993  		t, chain, db, params, moneyPkString, m1Pub,
   994  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   995  	_, _, _ = _doBasicTransferWithViewFlush(
   996  		t, chain, db, params, moneyPkString, m2Pub,
   997  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
   998  
   999  	// Create a post for m0
  1000  	_, postTxn, _, err := _doSubmitPostTxn(
  1001  		t, chain, db, params, feeRateNanosPerKB,
  1002  		m0Pub, m0Priv,
  1003  		nil,
  1004  		nil,
  1005  		"a post from m0",
  1006  		make(map[string][]byte),
  1007  		false)
  1008  	require.NoError(err)
  1009  
  1010  	// Create a profile for m0
  1011  	{
  1012  		_, _, _, err = _updateProfile(
  1013  			t, chain, db, params,
  1014  			feeRateNanosPerKB /*feerate*/, m0Pub,
  1015  			m0Priv, nil, "m0",
  1016  			"m0 profile", "",
  1017  			2500, /*CreatorBasisPoints*/
  1018  			12500 /*stakeMultipleBasisPoints*/, false /*isHidden*/)
  1019  		require.NoError(err)
  1020  	}
  1021  	// Create a profile for m1
  1022  	{
  1023  		_, _, _, err = _updateProfile(
  1024  			t, chain, db, params,
  1025  			feeRateNanosPerKB /*feerate*/, m1Pub,
  1026  			m1Priv, nil, "m1",
  1027  			"m1 profile", "",
  1028  			2500, /*CreatorBasisPoints*/
  1029  			12500 /*stakeMultipleBasisPoints*/, false /*isHidden*/)
  1030  		require.NoError(err)
  1031  	}
  1032  
  1033  	// Have m0 buy some of their own coin
  1034  	{
  1035  		_, _, _, err = _creatorCoinTxn(
  1036  			t, chain, db, params, feeRateNanosPerKB,
  1037  			m0Pub, m0Priv, /*updater*/
  1038  			m0Pub,                       /*profile*/
  1039  			CreatorCoinOperationTypeBuy, /*buy/sell*/
  1040  			1000000000,                  /*DeSoToSellNanos*/
  1041  			0,                           /*CreatorCoinToSellNanos*/
  1042  			0,                           /*DeSoToAddNanos*/
  1043  			0,                           /*MinDeSoExpectedNanos*/
  1044  			0 /*MinCreatorCoinExpectedNanos*/)
  1045  		require.NoError(err)
  1046  	}
  1047  	// Have m0 buy some m1 as well
  1048  	{
  1049  		_, _, _, err = _creatorCoinTxn(
  1050  			t, chain, db, params, feeRateNanosPerKB,
  1051  			m0Pub, m0Priv, /*updater*/
  1052  			m1Pub,                       /*profile*/
  1053  			CreatorCoinOperationTypeBuy, /*buy/sell*/
  1054  			1000000000,                  /*DeSoToSellNanos*/
  1055  			0,                           /*CreatorCoinToSellNanos*/
  1056  			0,                           /*DeSoToAddNanos*/
  1057  			0,                           /*MinDeSoExpectedNanos*/
  1058  			0 /*MinCreatorCoinExpectedNanos*/)
  1059  		require.NoError(err)
  1060  	}
  1061  
  1062  	// Missing a DiamondLevel should fail
  1063  	{
  1064  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1065  		require.NoError(err)
  1066  
  1067  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1068  		require.NoError(err)
  1069  
  1070  		utxoView, err := NewUtxoView(db, params, nil)
  1071  		require.NoError(err)
  1072  
  1073  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1074  			senderPkBytes,
  1075  			receiverPkBytes,
  1076  			postTxn.Hash(),
  1077  			5,
  1078  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1079  		require.NoError(err)
  1080  
  1081  		delete(txn.ExtraData, DiamondLevelKey)
  1082  
  1083  		// Sign the transaction now that its inputs are set up.
  1084  		_signTxn(t, txn, m0Priv)
  1085  
  1086  		txHash := txn.Hash()
  1087  		// Always use height+1 for validation since it's assumed the transaction will
  1088  		// get mined into the next block.
  1089  		blockHeight := chain.blockTip().Height + 1
  1090  		_, _, _, _, err =
  1091  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1092  		require.Error(err)
  1093  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferHasDiamondPostHashWithoutDiamondLevel)
  1094  	}
  1095  
  1096  	// An invalid DiamondLevel should fail
  1097  	{
  1098  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1099  		require.NoError(err)
  1100  
  1101  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1102  		require.NoError(err)
  1103  
  1104  		utxoView, err := NewUtxoView(db, params, nil)
  1105  		require.NoError(err)
  1106  
  1107  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1108  			senderPkBytes,
  1109  			receiverPkBytes,
  1110  			postTxn.Hash(),
  1111  			5,
  1112  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1113  		require.NoError(err)
  1114  
  1115  		txn.ExtraData[DiamondLevelKey] = IntToBuf(15)
  1116  
  1117  		// Sign the transaction now that its inputs are set up.
  1118  		_signTxn(t, txn, m0Priv)
  1119  
  1120  		txHash := txn.Hash()
  1121  		// Always use height+1 for validation since it's assumed the transaction will
  1122  		// get mined into the next block.
  1123  		blockHeight := chain.blockTip().Height + 1
  1124  		_, _, _, _, err =
  1125  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1126  		require.Error(err)
  1127  		require.Contains(err.Error(), "level 15 not allowed")
  1128  	}
  1129  	// A DiamondLevel of zero should fail
  1130  	{
  1131  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1132  		require.NoError(err)
  1133  
  1134  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1135  		require.NoError(err)
  1136  
  1137  		utxoView, err := NewUtxoView(db, params, nil)
  1138  		require.NoError(err)
  1139  
  1140  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1141  			senderPkBytes,
  1142  			receiverPkBytes,
  1143  			postTxn.Hash(),
  1144  			5,
  1145  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1146  		require.NoError(err)
  1147  
  1148  		txn.ExtraData[DiamondLevelKey] = IntToBuf(0)
  1149  
  1150  		// Sign the transaction now that its inputs are set up.
  1151  		_signTxn(t, txn, m0Priv)
  1152  
  1153  		txHash := txn.Hash()
  1154  		// Always use height+1 for validation since it's assumed the transaction will
  1155  		// get mined into the next block.
  1156  		blockHeight := chain.blockTip().Height + 1
  1157  		_, _, _, _, err =
  1158  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1159  		require.Error(err)
  1160  		require.Contains(err.Error(), "level 0 not allowed")
  1161  	}
  1162  	// You cannot give diamonds for profiles that are not your own.
  1163  	{
  1164  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1165  		require.NoError(err)
  1166  
  1167  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1168  		require.NoError(err)
  1169  
  1170  		utxoView, err := NewUtxoView(db, params, nil)
  1171  		require.NoError(err)
  1172  
  1173  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1174  			senderPkBytes,
  1175  			receiverPkBytes,
  1176  			postTxn.Hash(),
  1177  			5,
  1178  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1179  		require.NoError(err)
  1180  
  1181  		txn.TxnMeta.(*CreatorCoinTransferMetadataa).ProfilePublicKey = receiverPkBytes
  1182  
  1183  		// Sign the transaction now that its inputs are set up.
  1184  		_signTxn(t, txn, m0Priv)
  1185  
  1186  		txHash := txn.Hash()
  1187  		// Always use height+1 for validation since it's assumed the transaction will
  1188  		// get mined into the next block.
  1189  		blockHeight := chain.blockTip().Height + 1
  1190  		_, _, _, _, err =
  1191  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1192  		require.Error(err)
  1193  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferCantSendDiamondsForOtherProfiles)
  1194  	}
  1195  	// You can't Diamond yourself
  1196  	{
  1197  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1198  		require.NoError(err)
  1199  
  1200  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1201  		require.NoError(err)
  1202  
  1203  		utxoView, err := NewUtxoView(db, params, nil)
  1204  		require.NoError(err)
  1205  
  1206  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1207  			senderPkBytes,
  1208  			receiverPkBytes,
  1209  			postTxn.Hash(),
  1210  			5,
  1211  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1212  		require.NoError(err)
  1213  
  1214  		txn.TxnMeta.(*CreatorCoinTransferMetadataa).ReceiverPublicKey = senderPkBytes
  1215  
  1216  		// Sign the transaction now that its inputs are set up.
  1217  		_signTxn(t, txn, m0Priv)
  1218  
  1219  		txHash := txn.Hash()
  1220  		// Always use height+1 for validation since it's assumed the transaction will
  1221  		// get mined into the next block.
  1222  		blockHeight := chain.blockTip().Height + 1
  1223  		_, _, _, _, err =
  1224  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1225  		require.Error(err)
  1226  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferCannotTransferToSelf)
  1227  	}
  1228  	// You can't Diamond off a post that doesn't exist
  1229  	{
  1230  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1231  		require.NoError(err)
  1232  
  1233  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1234  		require.NoError(err)
  1235  
  1236  		utxoView, err := NewUtxoView(db, params, nil)
  1237  		require.NoError(err)
  1238  
  1239  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1240  			senderPkBytes,
  1241  			receiverPkBytes,
  1242  			postTxn.Hash(),
  1243  			5,
  1244  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1245  		require.NoError(err)
  1246  
  1247  		emptyHash := &BlockHash{}
  1248  		txn.ExtraData[DiamondPostHashKey] = emptyHash[:]
  1249  
  1250  		// Sign the transaction now that its inputs are set up.
  1251  		_signTxn(t, txn, m0Priv)
  1252  
  1253  		txHash := txn.Hash()
  1254  		// Always use height+1 for validation since it's assumed the transaction will
  1255  		// get mined into the next block.
  1256  		blockHeight := chain.blockTip().Height + 1
  1257  		_, _, _, _, err =
  1258  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1259  		require.Error(err)
  1260  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferDiamondPostEntryDoesNotExist)
  1261  	}
  1262  	// If you don't have enough creator coins, you can't Diamond
  1263  	{
  1264  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1265  		require.NoError(err)
  1266  
  1267  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1268  		require.NoError(err)
  1269  
  1270  		utxoView, err := NewUtxoView(db, params, nil)
  1271  		require.NoError(err)
  1272  
  1273  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1274  			receiverPkBytes,
  1275  			senderPkBytes,
  1276  			postTxn.Hash(),
  1277  			1,
  1278  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1279  		require.NoError(err)
  1280  
  1281  		txn.ExtraData[DiamondLevelKey] = IntToBuf(7)
  1282  
  1283  		// Sign the transaction now that its inputs are set up.
  1284  		_signTxn(t, txn, m1Priv)
  1285  
  1286  		txHash := txn.Hash()
  1287  		// Always use height+1 for validation since it's assumed the transaction will
  1288  		// get mined into the next block.
  1289  		blockHeight := chain.blockTip().Height + 1
  1290  		_, _, _, _, err =
  1291  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1292  		require.Error(err)
  1293  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferInsufficientCreatorCoinsForDiamondLevel)
  1294  	}
  1295  	// You can't apply the same number of Diamonds to a post twice
  1296  	{
  1297  		utxoView, err := NewUtxoView(db, params, nil)
  1298  		require.NoError(err)
  1299  
  1300  		// Let's have a successful transaction
  1301  		{
  1302  			senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1303  			require.NoError(err)
  1304  
  1305  			receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1306  			require.NoError(err)
  1307  
  1308  			txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1309  				senderPkBytes,
  1310  				receiverPkBytes,
  1311  				postTxn.Hash(),
  1312  				3,
  1313  				feeRateNanosPerKB, nil, []*DeSoOutput{})
  1314  			require.NoError(err)
  1315  
  1316  			// Sign the transaction now that its inputs are set up.
  1317  			_signTxn(t, txn, m0Priv)
  1318  
  1319  			txHash := txn.Hash()
  1320  			// Always use height+1 for validation since it's assumed the transaction will
  1321  			// get mined into the next block.
  1322  			blockHeight := chain.blockTip().Height + 1
  1323  			_, _, _, _, err =
  1324  				utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1325  			require.NoError(err)
  1326  			_, err = mempool.processTransaction(txn, false, false, 0, false)
  1327  			require.NoError(err)
  1328  		}
  1329  		// Now do a transaction with the same number of Diamonds
  1330  		{
  1331  			senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1332  			require.NoError(err)
  1333  
  1334  			receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1335  			require.NoError(err)
  1336  
  1337  			txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1338  				senderPkBytes,
  1339  				receiverPkBytes,
  1340  				postTxn.Hash(),
  1341  				5,
  1342  				feeRateNanosPerKB, mempool, []*DeSoOutput{})
  1343  			require.NoError(err)
  1344  
  1345  			txn.ExtraData[DiamondLevelKey] = IntToBuf(3)
  1346  
  1347  			// Sign the transaction now that its inputs are set up.
  1348  			_signTxn(t, txn, m0Priv)
  1349  
  1350  			txHash := txn.Hash()
  1351  			// Always use height+1 for validation since it's assumed the transaction will
  1352  			// get mined into the next block.
  1353  			blockHeight := chain.blockTip().Height + 1
  1354  			_, _, _, _, err =
  1355  				utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1356  			require.Error(err)
  1357  			require.Contains(err.Error(), RuleErrorCreatorCoinTransferPostAlreadyHasSufficientDiamonds)
  1358  		}
  1359  	}
  1360  }
  1361  
  1362  func TestCreatorCoinDiamondAfterDeSoDiamondsBlockHeight(t *testing.T) {
  1363  	// Set the DeSoDiamondsBlockHeight so that it is immediately hit.
  1364  	DeSoDiamondsBlockHeight = uint32(0)
  1365  
  1366  	// Set up a blockchain.
  1367  	assert := assert.New(t)
  1368  	require := require.New(t)
  1369  	_, _ = assert, require
  1370  
  1371  	chain, params, db := NewLowDifficultyBlockchain()
  1372  	mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/)
  1373  	feeRateNanosPerKB := uint64(11)
  1374  	_, _ = mempool, miner
  1375  
  1376  	// Create a paramUpdater for this test.
  1377  	params.ParamUpdaterPublicKeys[MakePkMapKey(paramUpdaterPkBytes)] = true
  1378  
  1379  	// Give paramUpdater some mony.
  1380  	_, _, _ = _doBasicTransferWithViewFlush(
  1381  		t, chain, db, params, moneyPkString, paramUpdaterPub,
  1382  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  1383  
  1384  	// Send money to people from moneyPk.
  1385  	_, _, _ = _doBasicTransferWithViewFlush(
  1386  		t, chain, db, params, moneyPkString, m0Pub,
  1387  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  1388  	_, _, _ = _doBasicTransferWithViewFlush(
  1389  		t, chain, db, params, moneyPkString, m1Pub,
  1390  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  1391  	_, _, _ = _doBasicTransferWithViewFlush(
  1392  		t, chain, db, params, moneyPkString, m2Pub,
  1393  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  1394  
  1395  	// Create a post for m0.
  1396  	_, postTxn, _, err := _doSubmitPostTxn(
  1397  		t, chain, db, params, feeRateNanosPerKB,
  1398  		m0Pub, m0Priv,
  1399  		nil,
  1400  		nil,
  1401  		"a post from m0",
  1402  		make(map[string][]byte),
  1403  		false)
  1404  	require.NoError(err)
  1405  
  1406  	// Create a profile for m0.
  1407  	{
  1408  		_, _, _, err = _updateProfile(
  1409  			t, chain, db, params,
  1410  			feeRateNanosPerKB /*feerate*/, m0Pub,
  1411  			m0Priv, nil, "m0",
  1412  			"m0 profile", "",
  1413  			2500, /*CreatorBasisPoints*/
  1414  			12500 /*stakeMultipleBasisPoints*/, false /*isHidden*/)
  1415  		require.NoError(err)
  1416  	}
  1417  	// Create a profile for m1.
  1418  	{
  1419  		_, _, _, err = _updateProfile(
  1420  			t, chain, db, params,
  1421  			feeRateNanosPerKB /*feerate*/, m1Pub,
  1422  			m1Priv, nil, "m1",
  1423  			"m1 profile", "",
  1424  			2500, /*CreatorBasisPoints*/
  1425  			12500 /*stakeMultipleBasisPoints*/, false /*isHidden*/)
  1426  		require.NoError(err)
  1427  	}
  1428  
  1429  	// Have m0 buy some of their own coin.
  1430  	{
  1431  		_, _, _, err = _creatorCoinTxn(
  1432  			t, chain, db, params, feeRateNanosPerKB,
  1433  			m0Pub, m0Priv, /*updater*/
  1434  			m0Pub,                       /*profile*/
  1435  			CreatorCoinOperationTypeBuy, /*buy/sell*/
  1436  			1000000000,                  /*DeSoToSellNanos*/
  1437  			0,                           /*CreatorCoinToSellNanos*/
  1438  			0,                           /*DeSoToAddNanos*/
  1439  			0,                           /*MinDeSoExpectedNanos*/
  1440  			0 /*MinCreatorCoinExpectedNanos*/)
  1441  		require.NoError(err)
  1442  	}
  1443  	// Have m0 buy some m1 as well.
  1444  	{
  1445  		_, _, _, err = _creatorCoinTxn(
  1446  			t, chain, db, params, feeRateNanosPerKB,
  1447  			m0Pub, m0Priv, /*updater*/
  1448  			m1Pub,                       /*profile*/
  1449  			CreatorCoinOperationTypeBuy, /*buy/sell*/
  1450  			1000000000,                  /*DeSoToSellNanos*/
  1451  			0,                           /*CreatorCoinToSellNanos*/
  1452  			0,                           /*DeSoToAddNanos*/
  1453  			0,                           /*MinDeSoExpectedNanos*/
  1454  			0 /*MinCreatorCoinExpectedNanos*/)
  1455  		require.NoError(err)
  1456  	}
  1457  
  1458  	// Adding diamonds after the DeSo Diamonds block height should fail.
  1459  	{
  1460  		senderPkBytes, _, err := Base58CheckDecode(m0Pub)
  1461  		require.NoError(err)
  1462  
  1463  		receiverPkBytes, _, err := Base58CheckDecode(m1Pub)
  1464  		require.NoError(err)
  1465  
  1466  		utxoView, err := NewUtxoView(db, params, nil)
  1467  		require.NoError(err)
  1468  
  1469  		// Attempt to give two diamonds.
  1470  		txn, _, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  1471  			senderPkBytes,
  1472  			receiverPkBytes,
  1473  			postTxn.Hash(),
  1474  			2,
  1475  			feeRateNanosPerKB, nil, []*DeSoOutput{})
  1476  		require.NoError(err)
  1477  
  1478  		// Sign the transaction now that its inputs are set up.
  1479  		_signTxn(t, txn, m0Priv)
  1480  
  1481  		txHash := txn.Hash()
  1482  		// Always use height+1 for validation since it's assumed the transaction will
  1483  		// get mined into the next block.
  1484  		blockHeight := chain.blockTip().Height + 1
  1485  		_, _, _, _, err =
  1486  			utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  1487  		require.Error(err)
  1488  		require.Contains(err.Error(), RuleErrorCreatorCoinTransferHasDiamondsAfterDeSoBlockHeight)
  1489  	}
  1490  }
  1491  
  1492  func TestCreatorCoinTransferSimple_CreatorCoinFounderReward(t *testing.T) {
  1493  	// Set up a blockchain
  1494  	assert := assert.New(t)
  1495  	require := require.New(t)
  1496  	_, _ = assert, require
  1497  
  1498  	creatorCoinTests := []*_CreatorCoinTestData{
  1499  		// Create a profile for m0
  1500  		{
  1501  			TxnType:                      TxnTypeUpdateProfile,
  1502  			UpdaterPublicKeyBase58Check:  m0Pub,
  1503  			UpdaterPrivateKeyBase58Check: m0Priv,
  1504  			ProfilePublicKeyBase58Check:  m0Pub,
  1505  			ProfileUsername:              "m0",
  1506  			ProfileDescription:           "i am m0",
  1507  			ProfilePic:                   "m0 profile pic",
  1508  			ProfileCreatorBasisPoints:    2500,
  1509  			ProfileIsHidden:              false,
  1510  
  1511  			SkipChecks: true,
  1512  		},
  1513  		// Have m1 buy some of m0's coins
  1514  		{
  1515  			// These are the transaction params
  1516  			UpdaterPublicKeyBase58Check:  m1Pub,
  1517  			UpdaterPrivateKeyBase58Check: m1Priv,
  1518  			ProfilePublicKeyBase58Check:  m0Pub,
  1519  			OperationType:                CreatorCoinOperationTypeBuy,
  1520  			DeSoToSellNanos:              1271123456,
  1521  			CreatorCoinToSellNanos:       0,
  1522  			DeSoToAddNanos:               0,
  1523  			MinDeSoExpectedNanos:         0,
  1524  			MinCreatorCoinExpectedNanos:  0,
  1525  
  1526  			// These are the expectations
  1527  			CoinsInCirculationNanos: 10832150315,
  1528  			DeSoLockedNanos:         1270996343,
  1529  			CoinWatermarkNanos:      10832150315,
  1530  			m0CCBalance:             2708037578,
  1531  			m0HasPurchased:          false,
  1532  			m1CCBalance:             8124112737,
  1533  			m1HasPurchased:          true,
  1534  			m2CCBalance:             0,
  1535  			m2HasPurchased:          false,
  1536  			m0DeSoBalance:           5999999998,
  1537  			m1DeSoBalance:           4728876542,
  1538  			m2DeSoBalance:           6000000000,
  1539  		},
  1540  		// Have m1 transfer some creator coins to m2
  1541  		{
  1542  			TxnType: TxnTypeCreatorCoinTransfer,
  1543  			// These are the transaction params
  1544  			UpdaterPublicKeyBase58Check:  m1Pub,
  1545  			UpdaterPrivateKeyBase58Check: m1Priv,
  1546  			ProfilePublicKeyBase58Check:  m0Pub,
  1547  			ReceiverPublicKeyBase58Check: m2Pub,
  1548  			CreatorCoinToTransferNanos:   1000000,
  1549  
  1550  			// These are the expectations
  1551  			CoinsInCirculationNanos: 10832150315,
  1552  			DeSoLockedNanos:         1270996343,
  1553  			CoinWatermarkNanos:      10832150315,
  1554  			m0CCBalance:             2708037578,
  1555  			m0HasPurchased:          false,
  1556  			m1CCBalance:             8123112737,
  1557  			m1HasPurchased:          true,
  1558  			m2CCBalance:             1000000,
  1559  			m2HasPurchased:          false,
  1560  			m0DeSoBalance:           5999999998,
  1561  			m1DeSoBalance:           4728876540,
  1562  			m2DeSoBalance:           6000000000,
  1563  		},
  1564  		// Have m1 transfer some more creator coins to m2
  1565  		{
  1566  			TxnType: TxnTypeCreatorCoinTransfer,
  1567  			// These are the transaction params
  1568  			UpdaterPublicKeyBase58Check:  m1Pub,
  1569  			UpdaterPrivateKeyBase58Check: m1Priv,
  1570  			ProfilePublicKeyBase58Check:  m0Pub,
  1571  			ReceiverPublicKeyBase58Check: m2Pub,
  1572  			CreatorCoinToTransferNanos:   20000000,
  1573  
  1574  			// These are the expectations
  1575  			CoinsInCirculationNanos: 10832150315,
  1576  			DeSoLockedNanos:         1270996343,
  1577  			CoinWatermarkNanos:      10832150315,
  1578  			m0CCBalance:             2708037578,
  1579  			m0HasPurchased:          false,
  1580  			m1CCBalance:             8103112737,
  1581  			m1HasPurchased:          true,
  1582  			m2CCBalance:             21000000,
  1583  			m2HasPurchased:          false,
  1584  			m0DeSoBalance:           5999999998,
  1585  			m1DeSoBalance:           4728876538,
  1586  			m2DeSoBalance:           6000000000,
  1587  		},
  1588  		// Have m1 transfer some more creator coins to m0
  1589  		{
  1590  			TxnType: TxnTypeCreatorCoinTransfer,
  1591  			// These are the transaction params
  1592  			UpdaterPublicKeyBase58Check:  m1Pub,
  1593  			UpdaterPrivateKeyBase58Check: m1Priv,
  1594  			ProfilePublicKeyBase58Check:  m0Pub,
  1595  			ReceiverPublicKeyBase58Check: m0Pub,
  1596  			CreatorCoinToTransferNanos:   8000000000,
  1597  
  1598  			// These are the expectations
  1599  			CoinsInCirculationNanos: 10832150315,
  1600  			DeSoLockedNanos:         1270996343,
  1601  			CoinWatermarkNanos:      10832150315,
  1602  			m0CCBalance:             10708037578,
  1603  			m0HasPurchased:          false,
  1604  			m1CCBalance:             103112737,
  1605  			m1HasPurchased:          true,
  1606  			m2CCBalance:             21000000,
  1607  			m2HasPurchased:          false,
  1608  			m0DeSoBalance:           5999999998,
  1609  			m1DeSoBalance:           4728876536,
  1610  			m2DeSoBalance:           6000000000,
  1611  		},
  1612  		// Have m1 transfer the rest of her creator coins to m0
  1613  		{
  1614  			TxnType: TxnTypeCreatorCoinTransfer,
  1615  			// These are the transaction params
  1616  			UpdaterPublicKeyBase58Check:  m1Pub,
  1617  			UpdaterPrivateKeyBase58Check: m1Priv,
  1618  			ProfilePublicKeyBase58Check:  m0Pub,
  1619  			ReceiverPublicKeyBase58Check: m0Pub,
  1620  			CreatorCoinToTransferNanos:   103112737,
  1621  
  1622  			// These are the expectations
  1623  			CoinsInCirculationNanos: 10832150315,
  1624  			DeSoLockedNanos:         1270996343,
  1625  			CoinWatermarkNanos:      10832150315,
  1626  			m0CCBalance:             10811150315,
  1627  			m0HasPurchased:          false,
  1628  			m1CCBalance:             0,
  1629  			m1HasPurchased:          false,
  1630  			m2CCBalance:             21000000,
  1631  			m2HasPurchased:          false,
  1632  			m0DeSoBalance:           5999999998,
  1633  			m1DeSoBalance:           4728876534,
  1634  			m2DeSoBalance:           6000000000,
  1635  		},
  1636  		// Have m0 transfer all coins back to m2
  1637  		{
  1638  			TxnType: TxnTypeCreatorCoinTransfer,
  1639  			// These are the transaction params
  1640  			UpdaterPublicKeyBase58Check:  m0Pub,
  1641  			UpdaterPrivateKeyBase58Check: m0Priv,
  1642  			ProfilePublicKeyBase58Check:  m0Pub,
  1643  			ReceiverPublicKeyBase58Check: m2Pub,
  1644  			CreatorCoinToTransferNanos:   10811150315,
  1645  
  1646  			// These are the expectations
  1647  			CoinsInCirculationNanos: 10832150315,
  1648  			DeSoLockedNanos:         1270996343,
  1649  			CoinWatermarkNanos:      10832150315,
  1650  			m0CCBalance:             0,
  1651  			m0HasPurchased:          false,
  1652  			m1CCBalance:             0,
  1653  			m1HasPurchased:          false,
  1654  			m2CCBalance:             10832150315,
  1655  			m2HasPurchased:          false,
  1656  			m0DeSoBalance:           5999999996,
  1657  			m1DeSoBalance:           4728876534,
  1658  			m2DeSoBalance:           6000000000,
  1659  		},
  1660  		// Have m2 transfer all coins back to m1. Weeeeee!!!
  1661  		{
  1662  			TxnType: TxnTypeCreatorCoinTransfer,
  1663  			// These are the transaction params
  1664  			UpdaterPublicKeyBase58Check:  m2Pub,
  1665  			UpdaterPrivateKeyBase58Check: m2Priv,
  1666  			ProfilePublicKeyBase58Check:  m0Pub,
  1667  			ReceiverPublicKeyBase58Check: m1Pub,
  1668  			CreatorCoinToTransferNanos:   10832150315,
  1669  
  1670  			// These are the expectations
  1671  			CoinsInCirculationNanos: 10832150315,
  1672  			DeSoLockedNanos:         1270996343,
  1673  			CoinWatermarkNanos:      10832150315,
  1674  			m0CCBalance:             0,
  1675  			m0HasPurchased:          false,
  1676  			m1CCBalance:             10832150315,
  1677  			m1HasPurchased:          false,
  1678  			m2CCBalance:             0,
  1679  			m2HasPurchased:          false,
  1680  			m0DeSoBalance:           5999999996,
  1681  			m1DeSoBalance:           4728876534,
  1682  			m2DeSoBalance:           5999999998,
  1683  		},
  1684  	}
  1685  
  1686  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false /*desoFounderReward*/)
  1687  }
  1688  
  1689  func TestCreatorCoinTransferSimple_DeSoFounderReward(t *testing.T) {
  1690  	// Set up a blockchain
  1691  	assert := assert.New(t)
  1692  	require := require.New(t)
  1693  	_, _ = assert, require
  1694  
  1695  	creatorCoinTests := []*_CreatorCoinTestData{
  1696  		// [0] Create a profile for m0
  1697  		{
  1698  			TxnType:                      TxnTypeUpdateProfile,
  1699  			UpdaterPublicKeyBase58Check:  m0Pub,
  1700  			UpdaterPrivateKeyBase58Check: m0Priv,
  1701  			ProfilePublicKeyBase58Check:  m0Pub,
  1702  			ProfileUsername:              "m0",
  1703  			ProfileDescription:           "i am m0",
  1704  			ProfilePic:                   "m0 profile pic",
  1705  			ProfileCreatorBasisPoints:    2500,
  1706  			ProfileIsHidden:              false,
  1707  
  1708  			SkipChecks: true,
  1709  		},
  1710  		// [1] Have m1 buy some of m0's coins
  1711  		{
  1712  			// These are the transaction params
  1713  			UpdaterPublicKeyBase58Check:  m1Pub,
  1714  			UpdaterPrivateKeyBase58Check: m1Priv,
  1715  			ProfilePublicKeyBase58Check:  m0Pub,
  1716  			OperationType:                CreatorCoinOperationTypeBuy,
  1717  			DeSoToSellNanos:              1271123456,
  1718  			CreatorCoinToSellNanos:       0,
  1719  			DeSoToAddNanos:               0,
  1720  			MinDeSoExpectedNanos:         0,
  1721  			MinCreatorCoinExpectedNanos:  0,
  1722  
  1723  			// These are the expectations
  1724  			CoinsInCirculationNanos: 9841661798,
  1725  			DeSoLockedNanos:         953247258,
  1726  			CoinWatermarkNanos:      9841661798,
  1727  			m0CCBalance:             0, // Founder reward is given in DeSo here.
  1728  			m0HasPurchased:          false,
  1729  			m1CCBalance:             9841661798,
  1730  			m1HasPurchased:          true,
  1731  			m2CCBalance:             0,
  1732  			m2HasPurchased:          false,
  1733  			m0DeSoBalance:           6317749083,
  1734  			m1DeSoBalance:           4728876542,
  1735  			m2DeSoBalance:           6000000000,
  1736  		},
  1737  		// [2] Have m1 transfer some creator coins to m2
  1738  		{
  1739  			TxnType: TxnTypeCreatorCoinTransfer,
  1740  			// These are the transaction params
  1741  			UpdaterPublicKeyBase58Check:  m1Pub,
  1742  			UpdaterPrivateKeyBase58Check: m1Priv,
  1743  			ProfilePublicKeyBase58Check:  m0Pub,
  1744  			ReceiverPublicKeyBase58Check: m2Pub,
  1745  			CreatorCoinToTransferNanos:   1000000,
  1746  
  1747  			// These are the expectations
  1748  			CoinsInCirculationNanos: 9841661798,
  1749  			DeSoLockedNanos:         953247258,
  1750  			CoinWatermarkNanos:      9841661798,
  1751  			m0CCBalance:             0,
  1752  			m0HasPurchased:          false,
  1753  			m1CCBalance:             9840661798,
  1754  			m1HasPurchased:          true,
  1755  			m2CCBalance:             1000000,
  1756  			m2HasPurchased:          false,
  1757  			m0DeSoBalance:           6317749083,
  1758  			m1DeSoBalance:           4728876540,
  1759  			m2DeSoBalance:           6000000000,
  1760  		},
  1761  		// [3] Have m1 transfer some more creator coins to m2
  1762  		{
  1763  			TxnType: TxnTypeCreatorCoinTransfer,
  1764  			// These are the transaction params
  1765  			UpdaterPublicKeyBase58Check:  m1Pub,
  1766  			UpdaterPrivateKeyBase58Check: m1Priv,
  1767  			ProfilePublicKeyBase58Check:  m0Pub,
  1768  			ReceiverPublicKeyBase58Check: m2Pub,
  1769  			CreatorCoinToTransferNanos:   20000000,
  1770  
  1771  			// These are the expectations
  1772  			CoinsInCirculationNanos: 9841661798,
  1773  			DeSoLockedNanos:         953247258,
  1774  			CoinWatermarkNanos:      9841661798,
  1775  			m0CCBalance:             0,
  1776  			m0HasPurchased:          false,
  1777  			m1CCBalance:             9820661798,
  1778  			m1HasPurchased:          true,
  1779  			m2CCBalance:             21000000,
  1780  			m2HasPurchased:          false,
  1781  			m0DeSoBalance:           6317749083,
  1782  			m1DeSoBalance:           4728876538,
  1783  			m2DeSoBalance:           6000000000,
  1784  		},
  1785  		// [4] Have m1 transfer some more creator coins to m0
  1786  		{
  1787  			TxnType: TxnTypeCreatorCoinTransfer,
  1788  			// These are the transaction params
  1789  			UpdaterPublicKeyBase58Check:  m1Pub,
  1790  			UpdaterPrivateKeyBase58Check: m1Priv,
  1791  			ProfilePublicKeyBase58Check:  m0Pub,
  1792  			ReceiverPublicKeyBase58Check: m0Pub,
  1793  			CreatorCoinToTransferNanos:   8000000000,
  1794  
  1795  			// These are the expectations
  1796  			CoinsInCirculationNanos: 9841661798,
  1797  			DeSoLockedNanos:         953247258,
  1798  			CoinWatermarkNanos:      9841661798,
  1799  			m0CCBalance:             8000000000,
  1800  			m0HasPurchased:          false,
  1801  			m1CCBalance:             1820661798,
  1802  			m1HasPurchased:          true,
  1803  			m2CCBalance:             21000000,
  1804  			m2HasPurchased:          false,
  1805  			m0DeSoBalance:           6317749083,
  1806  			m1DeSoBalance:           4728876536,
  1807  			m2DeSoBalance:           6000000000,
  1808  		},
  1809  		// [5] Have m1 transfer the rest of her creator coins to m0
  1810  		{
  1811  			TxnType: TxnTypeCreatorCoinTransfer,
  1812  			// These are the transaction params
  1813  			UpdaterPublicKeyBase58Check:  m1Pub,
  1814  			UpdaterPrivateKeyBase58Check: m1Priv,
  1815  			ProfilePublicKeyBase58Check:  m0Pub,
  1816  			ReceiverPublicKeyBase58Check: m0Pub,
  1817  			CreatorCoinToTransferNanos:   1820661798,
  1818  
  1819  			// These are the expectations
  1820  			CoinsInCirculationNanos: 9841661798,
  1821  			DeSoLockedNanos:         953247258,
  1822  			CoinWatermarkNanos:      9841661798,
  1823  			m0CCBalance:             9820661798,
  1824  			m0HasPurchased:          false,
  1825  			m1CCBalance:             0,
  1826  			m1HasPurchased:          false,
  1827  			m2CCBalance:             21000000,
  1828  			m2HasPurchased:          false,
  1829  			m0DeSoBalance:           6317749083,
  1830  			m1DeSoBalance:           4728876534,
  1831  			m2DeSoBalance:           6000000000,
  1832  		},
  1833  		// [6] Have m0 transfer all coins back to m2
  1834  		{
  1835  			TxnType: TxnTypeCreatorCoinTransfer,
  1836  			// These are the transaction params
  1837  			UpdaterPublicKeyBase58Check:  m0Pub,
  1838  			UpdaterPrivateKeyBase58Check: m0Priv,
  1839  			ProfilePublicKeyBase58Check:  m0Pub,
  1840  			ReceiverPublicKeyBase58Check: m2Pub,
  1841  			CreatorCoinToTransferNanos:   9820661798,
  1842  
  1843  			// These are the expectations
  1844  			CoinsInCirculationNanos: 9841661798,
  1845  			DeSoLockedNanos:         953247258,
  1846  			CoinWatermarkNanos:      9841661798,
  1847  			m0CCBalance:             0,
  1848  			m0HasPurchased:          false,
  1849  			m1CCBalance:             0,
  1850  			m1HasPurchased:          false,
  1851  			m2CCBalance:             9841661798,
  1852  			m2HasPurchased:          false,
  1853  			m0DeSoBalance:           6317749081,
  1854  			m1DeSoBalance:           4728876534,
  1855  			m2DeSoBalance:           6000000000,
  1856  		},
  1857  		// [7] Have m2 transfer all coins back to m1. Weeeeee!!!
  1858  		{
  1859  			TxnType: TxnTypeCreatorCoinTransfer,
  1860  			// These are the transaction params
  1861  			UpdaterPublicKeyBase58Check:  m2Pub,
  1862  			UpdaterPrivateKeyBase58Check: m2Priv,
  1863  			ProfilePublicKeyBase58Check:  m0Pub,
  1864  			ReceiverPublicKeyBase58Check: m1Pub,
  1865  			CreatorCoinToTransferNanos:   9841661798,
  1866  
  1867  			// These are the expectations
  1868  			CoinsInCirculationNanos: 9841661798,
  1869  			DeSoLockedNanos:         953247258,
  1870  			CoinWatermarkNanos:      9841661798,
  1871  			m0CCBalance:             0,
  1872  			m0HasPurchased:          false,
  1873  			m1CCBalance:             9841661798,
  1874  			m1HasPurchased:          false,
  1875  			m2CCBalance:             0,
  1876  			m2HasPurchased:          false,
  1877  			m0DeSoBalance:           6317749081,
  1878  			m1DeSoBalance:           4728876534,
  1879  			m2DeSoBalance:           5999999998,
  1880  		},
  1881  	}
  1882  
  1883  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, true /*desoFounderReward*/)
  1884  }
  1885  
  1886  func TestCreatorCoinTransferWithSwapIdentity(t *testing.T) {
  1887  	// Set up a blockchain
  1888  	assert := assert.New(t)
  1889  	require := require.New(t)
  1890  	_, _ = assert, require
  1891  
  1892  	creatorCoinTests := []*_CreatorCoinTestData{
  1893  		// Create a profile for m0
  1894  		{
  1895  			TxnType:                      TxnTypeUpdateProfile,
  1896  			UpdaterPublicKeyBase58Check:  m0Pub,
  1897  			UpdaterPrivateKeyBase58Check: m0Priv,
  1898  			ProfilePublicKeyBase58Check:  m0Pub,
  1899  			ProfileUsername:              "m0",
  1900  			ProfileDescription:           "i am m0",
  1901  			ProfilePic:                   "m0 profile pic",
  1902  			ProfileCreatorBasisPoints:    2500,
  1903  			ProfileIsHidden:              false,
  1904  
  1905  			SkipChecks: true,
  1906  		},
  1907  		// Have m1 buy some of m0's coins
  1908  		{
  1909  			// These are the transaction params
  1910  			UpdaterPublicKeyBase58Check:  m1Pub,
  1911  			UpdaterPrivateKeyBase58Check: m1Priv,
  1912  			ProfilePublicKeyBase58Check:  m0Pub,
  1913  			OperationType:                CreatorCoinOperationTypeBuy,
  1914  			DeSoToSellNanos:              1271123456,
  1915  			CreatorCoinToSellNanos:       0,
  1916  			DeSoToAddNanos:               0,
  1917  			MinDeSoExpectedNanos:         0,
  1918  			MinCreatorCoinExpectedNanos:  0,
  1919  
  1920  			// These are the expectations
  1921  			CoinsInCirculationNanos: 10832150315,
  1922  			DeSoLockedNanos:         1270996343,
  1923  			CoinWatermarkNanos:      10832150315,
  1924  			m0CCBalance:             2708037578,
  1925  			m0HasPurchased:          false,
  1926  			m1CCBalance:             8124112737,
  1927  			m1HasPurchased:          true,
  1928  			m2CCBalance:             0,
  1929  			m2HasPurchased:          false,
  1930  			m0DeSoBalance:           5999999998,
  1931  			m1DeSoBalance:           4728876542,
  1932  			m2DeSoBalance:           6000000000,
  1933  		},
  1934  		// Have m2 buy some of m0's coins
  1935  		{
  1936  			// These are the transaction params
  1937  			UpdaterPublicKeyBase58Check:  m2Pub,
  1938  			UpdaterPrivateKeyBase58Check: m2Priv,
  1939  			ProfilePublicKeyBase58Check:  m0Pub,
  1940  			OperationType:                CreatorCoinOperationTypeBuy,
  1941  			DeSoToSellNanos:              1172373183,
  1942  			CreatorCoinToSellNanos:       0,
  1943  			DeSoToAddNanos:               0,
  1944  			MinDeSoExpectedNanos:         0,
  1945  			MinCreatorCoinExpectedNanos:  0,
  1946  
  1947  			// These are the expectations
  1948  			CoinsInCirculationNanos: 13468606753,
  1949  			DeSoLockedNanos:         2443252288,
  1950  			CoinWatermarkNanos:      13468606753,
  1951  			m0CCBalance:             3367151687,
  1952  			m0HasPurchased:          false,
  1953  			m1CCBalance:             8124112737,
  1954  			m1HasPurchased:          true,
  1955  			m2CCBalance:             1977342329,
  1956  			m2HasPurchased:          true,
  1957  			m0DeSoBalance:           5999999998,
  1958  			m1DeSoBalance:           4728876542,
  1959  			m2DeSoBalance:           4827626815,
  1960  		},
  1961  		// Have m1 transfer 1e9 creator coins to m2
  1962  		{
  1963  			TxnType: TxnTypeCreatorCoinTransfer,
  1964  			// These are the transaction params
  1965  			UpdaterPublicKeyBase58Check:  m1Pub,
  1966  			UpdaterPrivateKeyBase58Check: m1Priv,
  1967  			ProfilePublicKeyBase58Check:  m0Pub,
  1968  			ReceiverPublicKeyBase58Check: m2Pub,
  1969  			CreatorCoinToTransferNanos:   1000000000,
  1970  
  1971  			// These are the expectations
  1972  			CoinsInCirculationNanos: 13468606753,
  1973  			DeSoLockedNanos:         2443252288,
  1974  			CoinWatermarkNanos:      13468606753,
  1975  			m0CCBalance:             3367151687,
  1976  			m0HasPurchased:          false,
  1977  			m1CCBalance:             7124112737,
  1978  			m1HasPurchased:          true,
  1979  			m2CCBalance:             2977342329,
  1980  			m2HasPurchased:          true,
  1981  			m0DeSoBalance:           5999999998,
  1982  			m1DeSoBalance:           4728876540,
  1983  			m2DeSoBalance:           4827626815,
  1984  		},
  1985  		// Swap m0 and m3
  1986  		{
  1987  			TxnType:       TxnTypeSwapIdentity,
  1988  			FromPublicKey: m0PkBytes,
  1989  			ToPublicKey:   m3PkBytes,
  1990  			// This is the creator whose coins we are testing the balances of.
  1991  			// Normally it's m0, but because we swapped m0 for m3 we should test
  1992  			// that one instead.
  1993  			ProfilePublicKeyBase58Check: m3Pub,
  1994  
  1995  			// These are the expectations
  1996  			CoinsInCirculationNanos: 13468606753,
  1997  			DeSoLockedNanos:         2443252288,
  1998  			CoinWatermarkNanos:      13468606753,
  1999  			m0CCBalance:             0,
  2000  			m0HasPurchased:          false,
  2001  			m1CCBalance:             7124112737,
  2002  			m1HasPurchased:          true,
  2003  			m2CCBalance:             2977342329,
  2004  			m2HasPurchased:          true,
  2005  			m3CCBalance:             3367151687,
  2006  			m3HasPurchased:          false,
  2007  			m0DeSoBalance:           5999999998,
  2008  			m1DeSoBalance:           4728876540,
  2009  			m2DeSoBalance:           4827626815,
  2010  		},
  2011  		// Have m2 transfer 2e9 creator coins (now attached to m3Pub's profile) to m0
  2012  		{
  2013  			TxnType: TxnTypeCreatorCoinTransfer,
  2014  			// These are the transaction params
  2015  			UpdaterPublicKeyBase58Check:  m2Pub,
  2016  			UpdaterPrivateKeyBase58Check: m2Priv,
  2017  			ProfilePublicKeyBase58Check:  m3Pub,
  2018  			ReceiverPublicKeyBase58Check: m0Pub,
  2019  			CreatorCoinToTransferNanos:   2000000000,
  2020  
  2021  			// These are the expectations
  2022  			CoinsInCirculationNanos: 13468606753,
  2023  			DeSoLockedNanos:         2443252288,
  2024  			CoinWatermarkNanos:      13468606753,
  2025  			m0CCBalance:             2000000000,
  2026  			m0HasPurchased:          false,
  2027  			m1CCBalance:             7124112737,
  2028  			m1HasPurchased:          true,
  2029  			m2CCBalance:             977342329,
  2030  			m2HasPurchased:          true,
  2031  			m3CCBalance:             3367151687,
  2032  			m3HasPurchased:          false,
  2033  			m0DeSoBalance:           5999999998,
  2034  			m1DeSoBalance:           4728876540,
  2035  			m2DeSoBalance:           4827626813,
  2036  		},
  2037  	}
  2038  
  2039  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  2040  }
  2041  
  2042  func TestCreatorCoinTransferWithSmallBalancesLeftOver(t *testing.T) {
  2043  	// Set up a blockchain
  2044  	assert := assert.New(t)
  2045  	require := require.New(t)
  2046  	_, _ = assert, require
  2047  
  2048  	creatorCoinTests := []*_CreatorCoinTestData{
  2049  		// Create a profile for m0
  2050  		{
  2051  			TxnType:                      TxnTypeUpdateProfile,
  2052  			UpdaterPublicKeyBase58Check:  m0Pub,
  2053  			UpdaterPrivateKeyBase58Check: m0Priv,
  2054  			ProfilePublicKeyBase58Check:  m0Pub,
  2055  			ProfileUsername:              "m0",
  2056  			ProfileDescription:           "i am m0",
  2057  			ProfilePic:                   "m0 profile pic",
  2058  			ProfileCreatorBasisPoints:    2500,
  2059  			ProfileIsHidden:              false,
  2060  
  2061  			SkipChecks: true,
  2062  		},
  2063  		// Have m1 buy some of m0's coins
  2064  		{
  2065  			// These are the transaction params
  2066  			UpdaterPublicKeyBase58Check:  m1Pub,
  2067  			UpdaterPrivateKeyBase58Check: m1Priv,
  2068  			ProfilePublicKeyBase58Check:  m0Pub,
  2069  			OperationType:                CreatorCoinOperationTypeBuy,
  2070  			DeSoToSellNanos:              1271123456,
  2071  			CreatorCoinToSellNanos:       0,
  2072  			DeSoToAddNanos:               0,
  2073  			MinDeSoExpectedNanos:         0,
  2074  			MinCreatorCoinExpectedNanos:  0,
  2075  
  2076  			// These are the expectations
  2077  			CoinsInCirculationNanos: 10832150315,
  2078  			DeSoLockedNanos:         1270996343,
  2079  			CoinWatermarkNanos:      10832150315,
  2080  			m0CCBalance:             2708037578,
  2081  			m0HasPurchased:          false,
  2082  			m1CCBalance:             8124112737,
  2083  			m1HasPurchased:          true,
  2084  			m2CCBalance:             0,
  2085  			m2HasPurchased:          false,
  2086  			m0DeSoBalance:           5999999998,
  2087  			m1DeSoBalance:           4728876542,
  2088  			m2DeSoBalance:           6000000000,
  2089  		},
  2090  		// Have m1 all but one nano of their creator coins to m2
  2091  		{
  2092  			TxnType: TxnTypeCreatorCoinTransfer,
  2093  			// These are the transaction params
  2094  			UpdaterPublicKeyBase58Check:  m1Pub,
  2095  			UpdaterPrivateKeyBase58Check: m1Priv,
  2096  			ProfilePublicKeyBase58Check:  m0Pub,
  2097  			ReceiverPublicKeyBase58Check: m2Pub,
  2098  			CreatorCoinToTransferNanos:   8124112736,
  2099  
  2100  			// These are the expectations
  2101  			CoinsInCirculationNanos: 10832150315,
  2102  			DeSoLockedNanos:         1270996343,
  2103  			CoinWatermarkNanos:      10832150315,
  2104  			m0CCBalance:             2708037578,
  2105  			m0HasPurchased:          false,
  2106  			m1CCBalance:             0,
  2107  			m1HasPurchased:          false,
  2108  			m2CCBalance:             8124112737,
  2109  			m2HasPurchased:          false,
  2110  			m0DeSoBalance:           5999999998,
  2111  			m1DeSoBalance:           4728876540,
  2112  			m2DeSoBalance:           6000000000,
  2113  		},
  2114  		// Have m2 transfer all but the min threshold back to m1 (threshold assumed to be 10 nanos).
  2115  		{
  2116  			TxnType: TxnTypeCreatorCoinTransfer,
  2117  			// These are the transaction params
  2118  			UpdaterPublicKeyBase58Check:  m2Pub,
  2119  			UpdaterPrivateKeyBase58Check: m2Priv,
  2120  			ProfilePublicKeyBase58Check:  m0Pub,
  2121  			ReceiverPublicKeyBase58Check: m1Pub,
  2122  			CreatorCoinToTransferNanos:   8124112727,
  2123  
  2124  			// These are the expectations
  2125  			CoinsInCirculationNanos: 10832150315,
  2126  			DeSoLockedNanos:         1270996343,
  2127  			CoinWatermarkNanos:      10832150315,
  2128  			m0CCBalance:             2708037578,
  2129  			m0HasPurchased:          false,
  2130  			m1CCBalance:             8124112727,
  2131  			m1HasPurchased:          false,
  2132  			m2CCBalance:             10,
  2133  			m2HasPurchased:          false,
  2134  			m0DeSoBalance:           5999999998,
  2135  			m1DeSoBalance:           4728876540,
  2136  			m2DeSoBalance:           5999999998,
  2137  		},
  2138  		// Have m2 transfer their remaining 10 nanos back to m1.
  2139  		{
  2140  			TxnType: TxnTypeCreatorCoinTransfer,
  2141  			// These are the transaction params
  2142  			UpdaterPublicKeyBase58Check:  m2Pub,
  2143  			UpdaterPrivateKeyBase58Check: m2Priv,
  2144  			ProfilePublicKeyBase58Check:  m0Pub,
  2145  			ReceiverPublicKeyBase58Check: m1Pub,
  2146  			CreatorCoinToTransferNanos:   10,
  2147  
  2148  			// These are the expectations
  2149  			CoinsInCirculationNanos: 10832150315,
  2150  			DeSoLockedNanos:         1270996343,
  2151  			CoinWatermarkNanos:      10832150315,
  2152  			m0CCBalance:             2708037578,
  2153  			m0HasPurchased:          false,
  2154  			m1CCBalance:             8124112737,
  2155  			m1HasPurchased:          false,
  2156  			m2CCBalance:             0,
  2157  			m2HasPurchased:          false,
  2158  			m0DeSoBalance:           5999999998,
  2159  			m1DeSoBalance:           4728876540,
  2160  			m2DeSoBalance:           5999999996,
  2161  		},
  2162  		// Have m1 transfer all but 5 nanos back to m0.
  2163  		{
  2164  			TxnType: TxnTypeCreatorCoinTransfer,
  2165  			// These are the transaction params
  2166  			UpdaterPublicKeyBase58Check:  m1Pub,
  2167  			UpdaterPrivateKeyBase58Check: m1Priv,
  2168  			ProfilePublicKeyBase58Check:  m0Pub,
  2169  			ReceiverPublicKeyBase58Check: m0Pub,
  2170  			CreatorCoinToTransferNanos:   8124112732,
  2171  
  2172  			// These are the expectations
  2173  			CoinsInCirculationNanos: 10832150315,
  2174  			DeSoLockedNanos:         1270996343,
  2175  			CoinWatermarkNanos:      10832150315,
  2176  			m0CCBalance:             10832150315,
  2177  			m0HasPurchased:          false,
  2178  			m1CCBalance:             0,
  2179  			m1HasPurchased:          false,
  2180  			m2CCBalance:             0,
  2181  			m2HasPurchased:          false,
  2182  			m0DeSoBalance:           5999999998,
  2183  			m1DeSoBalance:           4728876538,
  2184  			m2DeSoBalance:           5999999996,
  2185  		},
  2186  	}
  2187  
  2188  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  2189  }
  2190  
  2191  func TestCreatorCoinTransferWithMaxTransfers(t *testing.T) {
  2192  	// Set up a blockchain
  2193  	assert := assert.New(t)
  2194  	require := require.New(t)
  2195  	_, _ = assert, require
  2196  
  2197  	creatorCoinTests := []*_CreatorCoinTestData{
  2198  		// Create a profile for m0
  2199  		{
  2200  			TxnType:                      TxnTypeUpdateProfile,
  2201  			UpdaterPublicKeyBase58Check:  m0Pub,
  2202  			UpdaterPrivateKeyBase58Check: m0Priv,
  2203  			ProfilePublicKeyBase58Check:  m0Pub,
  2204  			ProfileUsername:              "m0",
  2205  			ProfileDescription:           "i am m0",
  2206  			ProfilePic:                   "m0 profile pic",
  2207  			ProfileCreatorBasisPoints:    2500,
  2208  			ProfileIsHidden:              false,
  2209  
  2210  			SkipChecks: true,
  2211  		},
  2212  		// Have m1 buy some of m0's coins
  2213  		{
  2214  			// These are the transaction params
  2215  			UpdaterPublicKeyBase58Check:  m1Pub,
  2216  			UpdaterPrivateKeyBase58Check: m1Priv,
  2217  			ProfilePublicKeyBase58Check:  m0Pub,
  2218  			OperationType:                CreatorCoinOperationTypeBuy,
  2219  			DeSoToSellNanos:              1271123456,
  2220  			CreatorCoinToSellNanos:       0,
  2221  			DeSoToAddNanos:               0,
  2222  			MinDeSoExpectedNanos:         0,
  2223  			MinCreatorCoinExpectedNanos:  0,
  2224  
  2225  			// These are the expectations
  2226  			CoinsInCirculationNanos: 10832150315,
  2227  			DeSoLockedNanos:         1270996343,
  2228  			CoinWatermarkNanos:      10832150315,
  2229  			m0CCBalance:             2708037578,
  2230  			m0HasPurchased:          false,
  2231  			m1CCBalance:             8124112737,
  2232  			m1HasPurchased:          true,
  2233  			m2CCBalance:             0,
  2234  			m2HasPurchased:          false,
  2235  			m0DeSoBalance:           5999999998,
  2236  			m1DeSoBalance:           4728876542,
  2237  			m2DeSoBalance:           6000000000,
  2238  		},
  2239  		// Have m1 send all of their creator coins to m2
  2240  		{
  2241  			TxnType: TxnTypeCreatorCoinTransfer,
  2242  			// These are the transaction params
  2243  			UpdaterPublicKeyBase58Check:  m1Pub,
  2244  			UpdaterPrivateKeyBase58Check: m1Priv,
  2245  			ProfilePublicKeyBase58Check:  m0Pub,
  2246  			ReceiverPublicKeyBase58Check: m2Pub,
  2247  			CreatorCoinToTransferNanos:   8124112737,
  2248  
  2249  			// These are the expectations
  2250  			CoinsInCirculationNanos: 10832150315,
  2251  			DeSoLockedNanos:         1270996343,
  2252  			CoinWatermarkNanos:      10832150315,
  2253  			m0CCBalance:             2708037578,
  2254  			m0HasPurchased:          false,
  2255  			m1CCBalance:             0,
  2256  			m1HasPurchased:          false,
  2257  			m2CCBalance:             8124112737,
  2258  			m2HasPurchased:          false,
  2259  			m0DeSoBalance:           5999999998,
  2260  			m1DeSoBalance:           4728876540,
  2261  			m2DeSoBalance:           6000000000,
  2262  		},
  2263  		// Have m1 buy some more of m0's coins
  2264  		{
  2265  			// These are the transaction params
  2266  			UpdaterPublicKeyBase58Check:  m1Pub,
  2267  			UpdaterPrivateKeyBase58Check: m1Priv,
  2268  			ProfilePublicKeyBase58Check:  m0Pub,
  2269  			OperationType:                CreatorCoinOperationTypeBuy,
  2270  			DeSoToSellNanos:              1271123456,
  2271  			CreatorCoinToSellNanos:       0,
  2272  			DeSoToAddNanos:               0,
  2273  			MinDeSoExpectedNanos:         0,
  2274  			MinCreatorCoinExpectedNanos:  0,
  2275  
  2276  			// These are the expectations
  2277  			CoinsInCirculationNanos: 13647653882,
  2278  			DeSoLockedNanos:         2541992686,
  2279  			CoinWatermarkNanos:      13647653882,
  2280  			m0CCBalance:             3411913469,
  2281  			m0HasPurchased:          false,
  2282  			m1CCBalance:             2111627676,
  2283  			m1HasPurchased:          true,
  2284  			m2CCBalance:             8124112737,
  2285  			m2HasPurchased:          false,
  2286  			m0DeSoBalance:           5999999998,
  2287  			m1DeSoBalance:           3457753082,
  2288  			m2DeSoBalance:           6000000000,
  2289  		},
  2290  		// Have m1 transfer all their m0 coins to m2
  2291  		{
  2292  			TxnType: TxnTypeCreatorCoinTransfer,
  2293  			// These are the transaction params
  2294  			UpdaterPublicKeyBase58Check:  m1Pub,
  2295  			UpdaterPrivateKeyBase58Check: m1Priv,
  2296  			ProfilePublicKeyBase58Check:  m0Pub,
  2297  			ReceiverPublicKeyBase58Check: m2Pub,
  2298  			CreatorCoinToTransferNanos:   2111627676,
  2299  
  2300  			// These are the expectations
  2301  			CoinsInCirculationNanos: 13647653882,
  2302  			DeSoLockedNanos:         2541992686,
  2303  			CoinWatermarkNanos:      13647653882,
  2304  			m0CCBalance:             3411913469,
  2305  			m0HasPurchased:          false,
  2306  			m1CCBalance:             0,
  2307  			m1HasPurchased:          false,
  2308  			m2CCBalance:             10235740413,
  2309  			m2HasPurchased:          false,
  2310  			m0DeSoBalance:           5999999998,
  2311  			m1DeSoBalance:           3457753080,
  2312  			m2DeSoBalance:           5999999998,
  2313  		},
  2314  	}
  2315  
  2316  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  2317  }
  2318  
  2319  func TestCreatorCoinTransferBelowMinThreshold(t *testing.T) {
  2320  	assert := assert.New(t)
  2321  	require := require.New(t)
  2322  	_, _ = assert, require
  2323  
  2324  	// Set up a blockchain
  2325  	chain, params, db := NewLowDifficultyBlockchain()
  2326  	mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/)
  2327  	feeRateNanosPerKB := uint64(11)
  2328  	_, _ = mempool, miner
  2329  
  2330  	// Send money to people from moneyPk
  2331  	_, _, _ = _doBasicTransferWithViewFlush(
  2332  		t, chain, db, params, moneyPkString, m0Pub,
  2333  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2334  	_, _, _ = _doBasicTransferWithViewFlush(
  2335  		t, chain, db, params, moneyPkString, m1Pub,
  2336  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2337  	_, _, _ = _doBasicTransferWithViewFlush(
  2338  		t, chain, db, params, moneyPkString, m2Pub,
  2339  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2340  	_, _, _ = _doBasicTransferWithViewFlush(
  2341  		t, chain, db, params, moneyPkString, m3Pub,
  2342  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2343  	_, _, _ = _doBasicTransferWithViewFlush(
  2344  		t, chain, db, params, moneyPkString, m4Pub,
  2345  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2346  	_, _, _ = _doBasicTransferWithViewFlush(
  2347  		t, chain, db, params, moneyPkString, m5Pub,
  2348  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2349  	_, _, _ = _doBasicTransferWithViewFlush(
  2350  		t, chain, db, params, moneyPkString, m6Pub,
  2351  		moneyPrivString, 6*NanosPerUnit /*amount to send*/, feeRateNanosPerKB /*feerate*/)
  2352  
  2353  	_, _, _, err := _updateProfile(
  2354  		t, chain, db, params,
  2355  		feeRateNanosPerKB /*feerate*/, m0Pub, m0Priv, m0PkBytes, "m0",
  2356  		"i am m0", "m0 profile pic", 2500, /*CreatorBasisPoints*/
  2357  		12500 /*stakeMultipleBasisPoints*/, false /*isHidden*/)
  2358  	require.NoError(err)
  2359  
  2360  	// m1 buys some m0 creator coin.
  2361  	_, _, _, err = _creatorCoinTxn(
  2362  		t, chain, db, params, feeRateNanosPerKB,
  2363  		m1Pub, m1Priv,
  2364  		m0Pub,                       /*profile*/
  2365  		CreatorCoinOperationTypeBuy, /*buy/sell*/
  2366  		1000000000,                  /*DeSoToSellNanos*/
  2367  		0,                           /*CreatorCoinToSellNanos*/
  2368  		0,                           /*DeSoToAddNanos*/
  2369  		0,                           /*MinDeSoExpectedNanos*/
  2370  		0 /*MinCreatorCoinExpectedNanos*/)
  2371  	require.NoError(err)
  2372  
  2373  	_, _, _, err = _doCreatorCoinTransferTxn(
  2374  		t, chain, db, params, feeRateNanosPerKB,
  2375  		m1Pub, m1Priv, m0Pub, m2Pub,
  2376  		mempool.bc.params.CreatorCoinAutoSellThresholdNanos-1)
  2377  	require.Contains(err.Error(), RuleErrorCreatorCoinTransferMustBeGreaterThanMinThreshold)
  2378  }
  2379  
  2380  func TestCreatorCoinBuySellSimple_CreatorCoinFounderReward(t *testing.T) {
  2381  	// Set up a blockchain
  2382  	assert := assert.New(t)
  2383  	require := require.New(t)
  2384  	_, _ = assert, require
  2385  
  2386  	creatorCoinTests := []*_CreatorCoinTestData{
  2387  		// Create a profile for m0
  2388  		{
  2389  			TxnType:                      TxnTypeUpdateProfile,
  2390  			UpdaterPublicKeyBase58Check:  m0Pub,
  2391  			UpdaterPrivateKeyBase58Check: m0Priv,
  2392  			ProfilePublicKeyBase58Check:  m0Pub,
  2393  			ProfileUsername:              "m0",
  2394  			ProfileDescription:           "i am m0",
  2395  			ProfilePic:                   "m0 profile pic",
  2396  			ProfileCreatorBasisPoints:    2500,
  2397  			ProfileIsHidden:              false,
  2398  
  2399  			SkipChecks: true,
  2400  		},
  2401  		// Have m1 buy some of m0's coins
  2402  		{
  2403  			// These are the transaction params
  2404  			UpdaterPublicKeyBase58Check:  m1Pub,
  2405  			UpdaterPrivateKeyBase58Check: m1Priv,
  2406  			ProfilePublicKeyBase58Check:  m0Pub,
  2407  			OperationType:                CreatorCoinOperationTypeBuy,
  2408  			DeSoToSellNanos:              1271123456,
  2409  			CreatorCoinToSellNanos:       0,
  2410  			DeSoToAddNanos:               0,
  2411  			MinDeSoExpectedNanos:         0,
  2412  			MinCreatorCoinExpectedNanos:  0,
  2413  
  2414  			// These are the expectations
  2415  			CoinsInCirculationNanos: 10832150315,
  2416  			DeSoLockedNanos:         1270996343,
  2417  			CoinWatermarkNanos:      10832150315,
  2418  			m0CCBalance:             2708037578,
  2419  			m0HasPurchased:          false,
  2420  			m1CCBalance:             8124112737,
  2421  			m1HasPurchased:          true,
  2422  			m2CCBalance:             0,
  2423  			m2HasPurchased:          false,
  2424  			m0DeSoBalance:           5999999998,
  2425  			m1DeSoBalance:           4728876542,
  2426  			m2DeSoBalance:           6000000000,
  2427  		},
  2428  		// Have m2 buy some of m0's coins
  2429  		{
  2430  			// These are the transaction params
  2431  			UpdaterPublicKeyBase58Check:  m2Pub,
  2432  			UpdaterPrivateKeyBase58Check: m2Priv,
  2433  			ProfilePublicKeyBase58Check:  m0Pub,
  2434  			OperationType:                CreatorCoinOperationTypeBuy,
  2435  			DeSoToSellNanos:              1172373183,
  2436  			CreatorCoinToSellNanos:       0,
  2437  			DeSoToAddNanos:               0,
  2438  			MinDeSoExpectedNanos:         0,
  2439  			MinCreatorCoinExpectedNanos:  0,
  2440  
  2441  			// These are the expectations
  2442  			CoinsInCirculationNanos: 13468606753,
  2443  			DeSoLockedNanos:         2443252288,
  2444  			CoinWatermarkNanos:      13468606753,
  2445  			m0CCBalance:             3367151687,
  2446  			m0HasPurchased:          false,
  2447  			m1CCBalance:             8124112737,
  2448  			m1HasPurchased:          true,
  2449  			m2CCBalance:             1977342329,
  2450  			m2HasPurchased:          true,
  2451  			m0DeSoBalance:           5999999998,
  2452  			m1DeSoBalance:           4728876542,
  2453  			m2DeSoBalance:           4827626815,
  2454  		},
  2455  		// Have m1 sell half of their stake
  2456  		{
  2457  			// These are the transaction params
  2458  			UpdaterPublicKeyBase58Check:  m1Pub,
  2459  			UpdaterPrivateKeyBase58Check: m1Priv,
  2460  			ProfilePublicKeyBase58Check:  m0Pub,
  2461  			OperationType:                CreatorCoinOperationTypeSell,
  2462  			DeSoToSellNanos:              0,
  2463  			CreatorCoinToSellNanos:       4123456789,
  2464  			DeSoToAddNanos:               0,
  2465  			MinDeSoExpectedNanos:         0,
  2466  			MinCreatorCoinExpectedNanos:  0,
  2467  
  2468  			// These are the expectations
  2469  			CoinsInCirculationNanos: 9345149964,
  2470  			DeSoLockedNanos:         816129494,
  2471  			CoinWatermarkNanos:      13468606753,
  2472  			m0CCBalance:             3367151687,
  2473  			m0HasPurchased:          false,
  2474  			m1CCBalance:             4000655948,
  2475  			m1HasPurchased:          true,
  2476  			m2CCBalance:             1977342329,
  2477  			m2HasPurchased:          true,
  2478  			m0DeSoBalance:           5999999998,
  2479  			m1DeSoBalance:           6355836621,
  2480  			m2DeSoBalance:           4827626815,
  2481  		},
  2482  		// Have m2 sell all of their stake
  2483  		{
  2484  			// These are the transaction params
  2485  			UpdaterPublicKeyBase58Check:  m2Pub,
  2486  			UpdaterPrivateKeyBase58Check: m2Priv,
  2487  			ProfilePublicKeyBase58Check:  m0Pub,
  2488  			OperationType:                CreatorCoinOperationTypeSell,
  2489  			DeSoToSellNanos:              0,
  2490  			CreatorCoinToSellNanos:       1977342329,
  2491  			DeSoToAddNanos:               0,
  2492  			MinDeSoExpectedNanos:         0,
  2493  			MinCreatorCoinExpectedNanos:  0,
  2494  
  2495  			// These are the expectations
  2496  			CoinsInCirculationNanos: 7367807635,
  2497  			DeSoLockedNanos:         399958612,
  2498  			CoinWatermarkNanos:      13468606753,
  2499  			m0CCBalance:             3367151687,
  2500  			m0HasPurchased:          false,
  2501  			m1CCBalance:             4000655948,
  2502  			m1HasPurchased:          true,
  2503  			m2CCBalance:             0,
  2504  			m2HasPurchased:          false,
  2505  			m0DeSoBalance:           5999999998,
  2506  			m1DeSoBalance:           6355836621,
  2507  			m2DeSoBalance:           5243756077,
  2508  		},
  2509  		// Have m1 buy more
  2510  		// Following SalomonFixBlockHeight, this should continue
  2511  		// to mint creator coins for the creator. Read about SalomonFixBlockHeight
  2512  		// in constants.go for a more indepth explanation.
  2513  		{
  2514  			// These are the transaction params
  2515  			UpdaterPublicKeyBase58Check:  m1Pub,
  2516  			UpdaterPrivateKeyBase58Check: m1Priv,
  2517  			ProfilePublicKeyBase58Check:  m0Pub,
  2518  			OperationType:                CreatorCoinOperationTypeBuy,
  2519  			DeSoToSellNanos:              2123456789,
  2520  			CreatorCoinToSellNanos:       0,
  2521  			DeSoToAddNanos:               0,
  2522  			MinDeSoExpectedNanos:         0,
  2523  			MinCreatorCoinExpectedNanos:  0,
  2524  
  2525  			// These are the expectations
  2526  			CoinsInCirculationNanos: 13613944261,
  2527  			DeSoLockedNanos:         2523203055,
  2528  			CoinWatermarkNanos:      13613944261,
  2529  			m0CCBalance:             4928685843,
  2530  			m0HasPurchased:          false,
  2531  			m1CCBalance:             8685258418,
  2532  			m1HasPurchased:          true,
  2533  			m2CCBalance:             0,
  2534  			m2HasPurchased:          false,
  2535  			m0DeSoBalance:           5999999998,
  2536  			m1DeSoBalance:           4232379830,
  2537  			m2DeSoBalance:           5243756077,
  2538  		},
  2539  
  2540  		// Have m1 sell the rest of their stake
  2541  		{
  2542  			// These are the transaction params
  2543  			UpdaterPublicKeyBase58Check:  m1Pub,
  2544  			UpdaterPrivateKeyBase58Check: m1Priv,
  2545  			ProfilePublicKeyBase58Check:  m0Pub,
  2546  			OperationType:                CreatorCoinOperationTypeSell,
  2547  			DeSoToSellNanos:              0,
  2548  			CreatorCoinToSellNanos:       8685258418,
  2549  			DeSoToAddNanos:               0,
  2550  			MinDeSoExpectedNanos:         0,
  2551  			MinCreatorCoinExpectedNanos:  0,
  2552  
  2553  			// These are the expectations
  2554  			CoinsInCirculationNanos: 4928685843,
  2555  			DeSoLockedNanos:         119727407,
  2556  			CoinWatermarkNanos:      13613944261,
  2557  			m0CCBalance:             4928685843,
  2558  			m0HasPurchased:          false,
  2559  			m1CCBalance:             0,
  2560  			m1HasPurchased:          false,
  2561  			m2CCBalance:             0,
  2562  			m2HasPurchased:          false,
  2563  			m0DeSoBalance:           5999999998,
  2564  			m1DeSoBalance:           6635615128,
  2565  			m2DeSoBalance:           5243756077,
  2566  		},
  2567  
  2568  		{
  2569  			// Have m0 sell all of their remaining stake except for 1 CreatorCoin nano
  2570  			// This will trigger an autosell due to CreatorCoinAutoSellThresholdNanos.
  2571  			// Nobody should be left with creator coins, and the deso locked should be zero.
  2572  			UpdaterPublicKeyBase58Check:  m0Pub,
  2573  			UpdaterPrivateKeyBase58Check: m0Priv,
  2574  			ProfilePublicKeyBase58Check:  m0Pub,
  2575  			OperationType:                CreatorCoinOperationTypeSell,
  2576  			DeSoToSellNanos:              0,
  2577  			CreatorCoinToSellNanos:       4928685842,
  2578  			DeSoToAddNanos:               0,
  2579  			MinDeSoExpectedNanos:         0,
  2580  			MinCreatorCoinExpectedNanos:  0,
  2581  
  2582  			// These are the expectations
  2583  			CoinsInCirculationNanos: 0,
  2584  			DeSoLockedNanos:         0,
  2585  			CoinWatermarkNanos:      13613944261,
  2586  			m0CCBalance:             0,
  2587  			m0HasPurchased:          false,
  2588  			m1CCBalance:             0,
  2589  			m1HasPurchased:          false,
  2590  			m2CCBalance:             0,
  2591  			m2HasPurchased:          false,
  2592  			m0DeSoBalance:           6119715430,
  2593  			m1DeSoBalance:           6635615128,
  2594  			m2DeSoBalance:           5243756077,
  2595  		},
  2596  
  2597  		// Have m1 buy a little more, again m0 should receive some more as a founders reward
  2598  		{
  2599  			// These are the transaction params
  2600  			UpdaterPublicKeyBase58Check:  m1Pub,
  2601  			UpdaterPrivateKeyBase58Check: m1Priv,
  2602  			ProfilePublicKeyBase58Check:  m0Pub,
  2603  			OperationType:                CreatorCoinOperationTypeBuy,
  2604  			DeSoToSellNanos:              2123456789,
  2605  			CreatorCoinToSellNanos:       0,
  2606  			DeSoToAddNanos:               0,
  2607  			MinDeSoExpectedNanos:         0,
  2608  			MinCreatorCoinExpectedNanos:  0,
  2609  
  2610  			// These are the expectations
  2611  			CoinsInCirculationNanos: 12852863707,
  2612  			DeSoLockedNanos:         2123244443,
  2613  			CoinWatermarkNanos:      13613944261,
  2614  			m0CCBalance:             3213215926,
  2615  			m0HasPurchased:          false,
  2616  			m1CCBalance:             9639647781,
  2617  			m1HasPurchased:          true,
  2618  			m2CCBalance:             0,
  2619  			m2HasPurchased:          false,
  2620  			m0DeSoBalance:           6119715430,
  2621  			m1DeSoBalance:           4512158337,
  2622  			m2DeSoBalance:           5243756077,
  2623  		},
  2624  
  2625  		// Have m1 sell their creator coins.
  2626  		{
  2627  			// These are the transaction params
  2628  			UpdaterPublicKeyBase58Check:  m1Pub,
  2629  			UpdaterPrivateKeyBase58Check: m1Priv,
  2630  			ProfilePublicKeyBase58Check:  m0Pub,
  2631  			OperationType:                CreatorCoinOperationTypeSell,
  2632  			DeSoToSellNanos:              0,
  2633  			CreatorCoinToSellNanos:       9639647781,
  2634  			DeSoToAddNanos:               0,
  2635  			MinDeSoExpectedNanos:         0,
  2636  			MinCreatorCoinExpectedNanos:  0,
  2637  
  2638  			// These are the expectations
  2639  			CoinsInCirculationNanos: 3213215926,
  2640  			DeSoLockedNanos:         33175681,
  2641  			CoinWatermarkNanos:      13613944261,
  2642  			m0CCBalance:             3213215926,
  2643  			m0HasPurchased:          false,
  2644  			m1CCBalance:             0,
  2645  			m1HasPurchased:          false,
  2646  			m2CCBalance:             0,
  2647  			m2HasPurchased:          false,
  2648  			m0DeSoBalance:           6119715430,
  2649  			m1DeSoBalance:           6602018090,
  2650  			m2DeSoBalance:           5243756077,
  2651  		},
  2652  	}
  2653  
  2654  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  2655  }
  2656  
  2657  func TestCreatorCoinBuySellSimple_DeSoFounderReward(t *testing.T) {
  2658  	// Set up a blockchain
  2659  	assert := assert.New(t)
  2660  	require := require.New(t)
  2661  	_, _ = assert, require
  2662  
  2663  	creatorCoinTests := []*_CreatorCoinTestData{
  2664  		// [0] Create a profile for m0
  2665  		{
  2666  			TxnType:                      TxnTypeUpdateProfile,
  2667  			UpdaterPublicKeyBase58Check:  m0Pub,
  2668  			UpdaterPrivateKeyBase58Check: m0Priv,
  2669  			ProfilePublicKeyBase58Check:  m0Pub,
  2670  			ProfileUsername:              "m0",
  2671  			ProfileDescription:           "i am m0",
  2672  			ProfilePic:                   "m0 profile pic",
  2673  			ProfileCreatorBasisPoints:    2500,
  2674  			ProfileIsHidden:              false,
  2675  
  2676  			SkipChecks: true,
  2677  		},
  2678  		// [1] Have m1 buy some of m0's coins
  2679  		{
  2680  			// These are the transaction params
  2681  			UpdaterPublicKeyBase58Check:  m1Pub,
  2682  			UpdaterPrivateKeyBase58Check: m1Priv,
  2683  			ProfilePublicKeyBase58Check:  m0Pub,
  2684  			OperationType:                CreatorCoinOperationTypeBuy,
  2685  			DeSoToSellNanos:              1271123456,
  2686  			CreatorCoinToSellNanos:       0,
  2687  			DeSoToAddNanos:               0,
  2688  			MinDeSoExpectedNanos:         0,
  2689  			MinCreatorCoinExpectedNanos:  0,
  2690  
  2691  			// These are the expectations
  2692  			CoinsInCirculationNanos: 9841661798,
  2693  			DeSoLockedNanos:         953247258,
  2694  			CoinWatermarkNanos:      9841661798,
  2695  			m0CCBalance:             0,
  2696  			m0HasPurchased:          false,
  2697  			m1CCBalance:             9841661798,
  2698  			m1HasPurchased:          true,
  2699  			m2CCBalance:             0,
  2700  			m2HasPurchased:          false,
  2701  			m0DeSoBalance:           6317749083,
  2702  			m1DeSoBalance:           4728876542,
  2703  			m2DeSoBalance:           6000000000,
  2704  		},
  2705  		// [2] Have m2 buy some of m0's coins
  2706  		{
  2707  			// These are the transaction params
  2708  			UpdaterPublicKeyBase58Check:  m2Pub,
  2709  			UpdaterPrivateKeyBase58Check: m2Priv,
  2710  			ProfilePublicKeyBase58Check:  m0Pub,
  2711  			OperationType:                CreatorCoinOperationTypeBuy,
  2712  			DeSoToSellNanos:              1172373183,
  2713  			CreatorCoinToSellNanos:       0,
  2714  			DeSoToAddNanos:               0,
  2715  			MinDeSoExpectedNanos:         0,
  2716  			MinCreatorCoinExpectedNanos:  0,
  2717  
  2718  			// These are the expectations
  2719  			CoinsInCirculationNanos: 12237041464,
  2720  			DeSoLockedNanos:         1832439217,
  2721  			CoinWatermarkNanos:      12237041464,
  2722  			m0CCBalance:             0,
  2723  			m0HasPurchased:          false,
  2724  			m1CCBalance:             9841661798,
  2725  			m1HasPurchased:          true,
  2726  			m2CCBalance:             2395379666,
  2727  			m2HasPurchased:          true,
  2728  			m0DeSoBalance:           6610813069,
  2729  			m1DeSoBalance:           4728876542,
  2730  			m2DeSoBalance:           4827626815,
  2731  		},
  2732  		// [3] Have m1 sell a large chunk of their stake
  2733  		{
  2734  			// These are the transaction params
  2735  			UpdaterPublicKeyBase58Check:  m1Pub,
  2736  			UpdaterPrivateKeyBase58Check: m1Priv,
  2737  			ProfilePublicKeyBase58Check:  m0Pub,
  2738  			OperationType:                CreatorCoinOperationTypeSell,
  2739  			DeSoToSellNanos:              0,
  2740  			CreatorCoinToSellNanos:       4123456789,
  2741  			DeSoToAddNanos:               0,
  2742  			MinDeSoExpectedNanos:         0,
  2743  			MinCreatorCoinExpectedNanos:  0,
  2744  
  2745  			// These are the expectations
  2746  			CoinsInCirculationNanos: 8113584675,
  2747  			DeSoLockedNanos:         534119641,
  2748  			CoinWatermarkNanos:      12237041464,
  2749  			m0CCBalance:             0,
  2750  			m0HasPurchased:          false,
  2751  			m1CCBalance:             5718205009,
  2752  			m1HasPurchased:          true,
  2753  			m2CCBalance:             2395379666,
  2754  			m2HasPurchased:          true,
  2755  			m0DeSoBalance:           6610813069,
  2756  			m1DeSoBalance:           6027066284,
  2757  			m2DeSoBalance:           4827626815,
  2758  		},
  2759  		// [4] Have m2 sell all of their stake
  2760  		{
  2761  			// These are the transaction params
  2762  			UpdaterPublicKeyBase58Check:  m2Pub,
  2763  			UpdaterPrivateKeyBase58Check: m2Priv,
  2764  			ProfilePublicKeyBase58Check:  m0Pub,
  2765  			OperationType:                CreatorCoinOperationTypeSell,
  2766  			DeSoToSellNanos:              0,
  2767  			CreatorCoinToSellNanos:       2395379666,
  2768  			DeSoToAddNanos:               0,
  2769  			MinDeSoExpectedNanos:         0,
  2770  			MinCreatorCoinExpectedNanos:  0,
  2771  
  2772  			// These are the expectations
  2773  			CoinsInCirculationNanos: 5718205009,
  2774  			DeSoLockedNanos:         186973195,
  2775  			CoinWatermarkNanos:      12237041464,
  2776  			m0CCBalance:             0,
  2777  			m0HasPurchased:          false,
  2778  			m1CCBalance:             5718205009,
  2779  			m1HasPurchased:          true,
  2780  			m2CCBalance:             0,
  2781  			m2HasPurchased:          false,
  2782  			m0DeSoBalance:           6610813069,
  2783  			m1DeSoBalance:           6027066284,
  2784  			m2DeSoBalance:           5174738544,
  2785  		},
  2786  		// [5] Have m1 buy more
  2787  		// Following SalomonFixBlockHeight, this should continue
  2788  		// to mint creator coins / deso for the creator. Read about SalomonFixBlockHeight
  2789  		// in constants.go for a more indepth explanation.
  2790  		{
  2791  			// These are the transaction params
  2792  			UpdaterPublicKeyBase58Check:  m1Pub,
  2793  			UpdaterPrivateKeyBase58Check: m1Priv,
  2794  			ProfilePublicKeyBase58Check:  m0Pub,
  2795  			OperationType:                CreatorCoinOperationTypeBuy,
  2796  			DeSoToSellNanos:              2123456789,
  2797  			CreatorCoinToSellNanos:       0,
  2798  			DeSoToAddNanos:               0,
  2799  			MinDeSoExpectedNanos:         0,
  2800  			MinCreatorCoinExpectedNanos:  0,
  2801  
  2802  			// These are the expectations
  2803  			CoinsInCirculationNanos: 12117833075,
  2804  			DeSoLockedNanos:         1779406528,
  2805  			CoinWatermarkNanos:      12237041464,
  2806  			m0CCBalance:             0,
  2807  			m0HasPurchased:          false,
  2808  			m1CCBalance:             12117833075,
  2809  			m1HasPurchased:          true,
  2810  			m2CCBalance:             0,
  2811  			m2HasPurchased:          false,
  2812  			m0DeSoBalance:           7141624179,
  2813  			m1DeSoBalance:           3903609493,
  2814  			m2DeSoBalance:           5174738544,
  2815  		},
  2816  
  2817  		// [6] Have m1 sell the rest of their stake
  2818  		{
  2819  			// These are the transaction params
  2820  			UpdaterPublicKeyBase58Check:  m1Pub,
  2821  			UpdaterPrivateKeyBase58Check: m1Priv,
  2822  			ProfilePublicKeyBase58Check:  m0Pub,
  2823  			OperationType:                CreatorCoinOperationTypeSell,
  2824  			DeSoToSellNanos:              0,
  2825  			CreatorCoinToSellNanos:       12117833075,
  2826  			DeSoToAddNanos:               0,
  2827  			MinDeSoExpectedNanos:         0,
  2828  			MinCreatorCoinExpectedNanos:  0,
  2829  
  2830  			// These are the expectations
  2831  			CoinsInCirculationNanos: 0,
  2832  			DeSoLockedNanos:         0,
  2833  			CoinWatermarkNanos:      12237041464,
  2834  			m0CCBalance:             0,
  2835  			m0HasPurchased:          false,
  2836  			m1CCBalance:             0,
  2837  			m1HasPurchased:          false,
  2838  			m2CCBalance:             0,
  2839  			m2HasPurchased:          false,
  2840  			m0DeSoBalance:           7141624179,
  2841  			m1DeSoBalance:           5682838078,
  2842  			m2DeSoBalance:           5174738544,
  2843  		},
  2844  
  2845  		// [7] Have m0 buy some of their own coins.
  2846  		{
  2847  			// These are the transaction params
  2848  			UpdaterPublicKeyBase58Check:  m0Pub,
  2849  			UpdaterPrivateKeyBase58Check: m0Priv,
  2850  			ProfilePublicKeyBase58Check:  m0Pub,
  2851  			OperationType:                CreatorCoinOperationTypeBuy,
  2852  			DeSoToSellNanos:              1e6,
  2853  			CreatorCoinToSellNanos:       0,
  2854  			DeSoToAddNanos:               0,
  2855  			MinDeSoExpectedNanos:         0,
  2856  			MinCreatorCoinExpectedNanos:  0,
  2857  
  2858  			// These are the expectations
  2859  			CoinsInCirculationNanos: 999966698,
  2860  			DeSoLockedNanos:         999900,
  2861  			CoinWatermarkNanos:      12237041464,
  2862  			m0CCBalance:             999966698,
  2863  			m0HasPurchased:          true,
  2864  			m1CCBalance:             0,
  2865  			m1HasPurchased:          false,
  2866  			m2CCBalance:             0,
  2867  			m2HasPurchased:          false,
  2868  			m0DeSoBalance:           7140624177,
  2869  			m1DeSoBalance:           5682838078,
  2870  			m2DeSoBalance:           5174738544,
  2871  		},
  2872  
  2873  		{
  2874  			// [8] Have m0 sell all of their remaining stake except for 1 CreatorCoin nano
  2875  			// This will trigger an autosell due to CreatorCoinAutoSellThresholdNanos.
  2876  			// Nobody should be left with creator coins, and the deso locked should be zero.
  2877  			UpdaterPublicKeyBase58Check:  m0Pub,
  2878  			UpdaterPrivateKeyBase58Check: m0Priv,
  2879  			ProfilePublicKeyBase58Check:  m0Pub,
  2880  			OperationType:                CreatorCoinOperationTypeSell,
  2881  			DeSoToSellNanos:              0,
  2882  			CreatorCoinToSellNanos:       999966697,
  2883  			DeSoToAddNanos:               0,
  2884  			MinDeSoExpectedNanos:         0,
  2885  			MinCreatorCoinExpectedNanos:  0,
  2886  
  2887  			// These are the expectations
  2888  			CoinsInCirculationNanos: 0,
  2889  			DeSoLockedNanos:         0,
  2890  			CoinWatermarkNanos:      12237041464,
  2891  			m0CCBalance:             0,
  2892  			m0HasPurchased:          false,
  2893  			m1CCBalance:             0,
  2894  			m1HasPurchased:          false,
  2895  			m2CCBalance:             0,
  2896  			m2HasPurchased:          false,
  2897  			m0DeSoBalance:           7141623975,
  2898  			m1DeSoBalance:           5682838078,
  2899  			m2DeSoBalance:           5174738544,
  2900  		},
  2901  
  2902  		// [9] Have m1 buy a little more, again m0 should receive some deso as a founders reward
  2903  		{
  2904  			// These are the transaction params
  2905  			UpdaterPublicKeyBase58Check:  m1Pub,
  2906  			UpdaterPrivateKeyBase58Check: m1Priv,
  2907  			ProfilePublicKeyBase58Check:  m0Pub,
  2908  			OperationType:                CreatorCoinOperationTypeBuy,
  2909  			DeSoToSellNanos:              2123456789,
  2910  			CreatorCoinToSellNanos:       0,
  2911  			DeSoToAddNanos:               0,
  2912  			MinDeSoExpectedNanos:         0,
  2913  			MinCreatorCoinExpectedNanos:  0,
  2914  
  2915  			// These are the expectations
  2916  			CoinsInCirculationNanos: 11677601773,
  2917  			DeSoLockedNanos:         1592433333,
  2918  			CoinWatermarkNanos:      12237041464,
  2919  			m0CCBalance:             0,
  2920  			m0HasPurchased:          false,
  2921  			m1CCBalance:             11677601773,
  2922  			m1HasPurchased:          true,
  2923  			m2CCBalance:             0,
  2924  			m2HasPurchased:          false,
  2925  			m0DeSoBalance:           7672435085,
  2926  			m1DeSoBalance:           3559381287,
  2927  			m2DeSoBalance:           5174738544,
  2928  		},
  2929  
  2930  		// [10] Have m1 sell their creator coins.
  2931  		{
  2932  			// These are the transaction params
  2933  			UpdaterPublicKeyBase58Check:  m1Pub,
  2934  			UpdaterPrivateKeyBase58Check: m1Priv,
  2935  			ProfilePublicKeyBase58Check:  m0Pub,
  2936  			OperationType:                CreatorCoinOperationTypeSell,
  2937  			DeSoToSellNanos:              0,
  2938  			CreatorCoinToSellNanos:       11677601773,
  2939  			DeSoToAddNanos:               0,
  2940  			MinDeSoExpectedNanos:         0,
  2941  			MinCreatorCoinExpectedNanos:  0,
  2942  
  2943  			// These are the expectations
  2944  			CoinsInCirculationNanos: 0,
  2945  			DeSoLockedNanos:         0,
  2946  			CoinWatermarkNanos:      12237041464,
  2947  			m0CCBalance:             0,
  2948  			m0HasPurchased:          false,
  2949  			m1CCBalance:             0,
  2950  			m1HasPurchased:          false,
  2951  			m2CCBalance:             0,
  2952  			m2HasPurchased:          false,
  2953  			m0DeSoBalance:           7672435085,
  2954  			m1DeSoBalance:           5151655374,
  2955  			m2DeSoBalance:           5174738544,
  2956  		},
  2957  	}
  2958  
  2959  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, true)
  2960  }
  2961  
  2962  // This test exercises some logic whereby a creator buys and
  2963  // sells their own coin before anybody else.
  2964  func TestCreatorCoinSelfBuying_DeSoAndCreatorCoinFounderReward(t *testing.T) {
  2965  	// Set up a blockchain
  2966  	assert := assert.New(t)
  2967  	require := require.New(t)
  2968  	_, _ = assert, require
  2969  
  2970  	creatorCoinTests := []*_CreatorCoinTestData{
  2971  		// Create a profile for m0
  2972  		{
  2973  			TxnType:                      TxnTypeUpdateProfile,
  2974  			UpdaterPublicKeyBase58Check:  m0Pub,
  2975  			UpdaterPrivateKeyBase58Check: m0Priv,
  2976  			ProfilePublicKeyBase58Check:  m0Pub,
  2977  			ProfileUsername:              "m0",
  2978  			ProfileDescription:           "i am m0",
  2979  			ProfilePic:                   "m0 profile pic",
  2980  			ProfileCreatorBasisPoints:    2500,
  2981  			ProfileIsHidden:              false,
  2982  
  2983  			SkipChecks: true,
  2984  		},
  2985  		// Have m0 buy his own coins
  2986  		{
  2987  			// These are the transaction params
  2988  			UpdaterPublicKeyBase58Check:  m0Pub,
  2989  			UpdaterPrivateKeyBase58Check: m0Priv,
  2990  			ProfilePublicKeyBase58Check:  m0Pub,
  2991  			OperationType:                CreatorCoinOperationTypeBuy,
  2992  			DeSoToSellNanos:              1271123456,
  2993  			CreatorCoinToSellNanos:       0,
  2994  			DeSoToAddNanos:               0,
  2995  			MinDeSoExpectedNanos:         0,
  2996  			MinCreatorCoinExpectedNanos:  0,
  2997  
  2998  			// These are the expectations
  2999  			CoinsInCirculationNanos: 10832150315,
  3000  			DeSoLockedNanos:         1270996343,
  3001  			CoinWatermarkNanos:      10832150315,
  3002  			m0CCBalance:             10832150315,
  3003  			m0HasPurchased:          true,
  3004  			m1CCBalance:             0,
  3005  			m1HasPurchased:          false,
  3006  			m2CCBalance:             0,
  3007  			m2HasPurchased:          false,
  3008  			m0DeSoBalance:           4728876540,
  3009  			m1DeSoBalance:           6000000000,
  3010  			m2DeSoBalance:           6000000000,
  3011  		},
  3012  		// Have m0 buy his own coins *again*
  3013  		{
  3014  			// These are the transaction params
  3015  			UpdaterPublicKeyBase58Check:  m0Pub,
  3016  			UpdaterPrivateKeyBase58Check: m0Priv,
  3017  			ProfilePublicKeyBase58Check:  m0Pub,
  3018  			OperationType:                CreatorCoinOperationTypeBuy,
  3019  			DeSoToSellNanos:              1172373183,
  3020  			CreatorCoinToSellNanos:       0,
  3021  			DeSoToAddNanos:               0,
  3022  			MinDeSoExpectedNanos:         0,
  3023  			MinCreatorCoinExpectedNanos:  0,
  3024  
  3025  			// These are the expectations
  3026  			CoinsInCirculationNanos: 13468606753,
  3027  			DeSoLockedNanos:         2443252288,
  3028  			CoinWatermarkNanos:      13468606753,
  3029  			m0CCBalance:             13468606753,
  3030  			m0HasPurchased:          true,
  3031  			m1CCBalance:             0,
  3032  			m1HasPurchased:          false,
  3033  			m2CCBalance:             0,
  3034  			m2HasPurchased:          false,
  3035  			m0DeSoBalance:           3556503355,
  3036  			m1DeSoBalance:           6000000000,
  3037  			m2DeSoBalance:           6000000000,
  3038  		},
  3039  		// Have m0 sell half of his own coins
  3040  		{
  3041  			// These are the transaction params
  3042  			UpdaterPublicKeyBase58Check:  m0Pub,
  3043  			UpdaterPrivateKeyBase58Check: m0Priv,
  3044  			ProfilePublicKeyBase58Check:  m0Pub,
  3045  			OperationType:                CreatorCoinOperationTypeSell,
  3046  			DeSoToSellNanos:              0,
  3047  			CreatorCoinToSellNanos:       1556503355,
  3048  			DeSoToAddNanos:               0,
  3049  			MinDeSoExpectedNanos:         0,
  3050  			MinCreatorCoinExpectedNanos:  0,
  3051  
  3052  			// These are the expectations
  3053  			CoinsInCirculationNanos: 11912103398,
  3054  			DeSoLockedNanos:         1690307207,
  3055  			CoinWatermarkNanos:      13468606753,
  3056  			m0CCBalance:             11912103398,
  3057  			m0HasPurchased:          true,
  3058  			m1CCBalance:             0,
  3059  			m1HasPurchased:          false,
  3060  			m2CCBalance:             0,
  3061  			m2HasPurchased:          false,
  3062  			m0DeSoBalance:           4309373139,
  3063  			m1DeSoBalance:           6000000000,
  3064  			m2DeSoBalance:           6000000000,
  3065  		},
  3066  		// Have m0 sell the rest of his own coins
  3067  		{
  3068  			// These are the transaction params
  3069  			UpdaterPublicKeyBase58Check:  m0Pub,
  3070  			UpdaterPrivateKeyBase58Check: m0Priv,
  3071  			ProfilePublicKeyBase58Check:  m0Pub,
  3072  			OperationType:                CreatorCoinOperationTypeSell,
  3073  			DeSoToSellNanos:              0,
  3074  			CreatorCoinToSellNanos:       11912103398,
  3075  			DeSoToAddNanos:               0,
  3076  			MinDeSoExpectedNanos:         0,
  3077  			MinCreatorCoinExpectedNanos:  0,
  3078  
  3079  			// These are the expectations
  3080  			CoinsInCirculationNanos: 0,
  3081  			DeSoLockedNanos:         0,
  3082  			CoinWatermarkNanos:      13468606753,
  3083  			m0CCBalance:             0,
  3084  			m0HasPurchased:          false,
  3085  			m1CCBalance:             0,
  3086  			m1HasPurchased:          false,
  3087  			m2CCBalance:             0,
  3088  			m2HasPurchased:          false,
  3089  			m0DeSoBalance:           5999511313,
  3090  			m1DeSoBalance:           6000000000,
  3091  			m2DeSoBalance:           6000000000,
  3092  		},
  3093  	}
  3094  
  3095  	// Buying one's own coin should always result in a creator coin founder reward,
  3096  	// even after the deso founder reward block height.
  3097  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false /*desoFounderReward*/)
  3098  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, true /*desoFounderReward*/)
  3099  }
  3100  
  3101  func TestCreatorCoinTinyFounderRewardBuySellAmounts_CreatorCoinFounderReward(t *testing.T) {
  3102  	// Set up a blockchain
  3103  	assert := assert.New(t)
  3104  	require := require.New(t)
  3105  	_, _ = assert, require
  3106  
  3107  	creatorCoinTests := []*_CreatorCoinTestData{
  3108  		// Create a profile for m0
  3109  		{
  3110  			TxnType:                      TxnTypeUpdateProfile,
  3111  			UpdaterPublicKeyBase58Check:  m0Pub,
  3112  			UpdaterPrivateKeyBase58Check: m0Priv,
  3113  			ProfilePublicKeyBase58Check:  m0Pub,
  3114  			ProfileUsername:              "m0",
  3115  			ProfileDescription:           "i am m0",
  3116  			ProfilePic:                   "m0 profile pic",
  3117  			ProfileCreatorBasisPoints:    1,
  3118  			ProfileIsHidden:              false,
  3119  
  3120  			SkipChecks: true,
  3121  		},
  3122  		// Have m1 buy a large amount of m0 to push up the watermark
  3123  		{
  3124  			UpdaterPublicKeyBase58Check:  m1Pub,
  3125  			UpdaterPrivateKeyBase58Check: m1Priv,
  3126  			ProfilePublicKeyBase58Check:  m0Pub,
  3127  			OperationType:                CreatorCoinOperationTypeBuy,
  3128  			DeSoToSellNanos:              100000000,
  3129  			CreatorCoinToSellNanos:       0,
  3130  			DeSoToAddNanos:               0,
  3131  			MinDeSoExpectedNanos:         0,
  3132  			MinCreatorCoinExpectedNanos:  0,
  3133  
  3134  			// These are the expectations
  3135  			CoinsInCirculationNanos: 4641433551,
  3136  			DeSoLockedNanos:         99990000,
  3137  			CoinWatermarkNanos:      4641433551,
  3138  			m0CCBalance:             464143,
  3139  			m0HasPurchased:          false,
  3140  			m1CCBalance:             4640969408,
  3141  			m1HasPurchased:          true,
  3142  			m2CCBalance:             0,
  3143  			m2HasPurchased:          false,
  3144  			m0DeSoBalance:           5999999998,
  3145  			m1DeSoBalance:           5899999998,
  3146  			m2DeSoBalance:           6000000000,
  3147  		},
  3148  		// Have m0 sell all their coins such that they're below the autosell threshold
  3149  		{
  3150  			UpdaterPublicKeyBase58Check:  m0Pub,
  3151  			UpdaterPrivateKeyBase58Check: m0Priv,
  3152  			ProfilePublicKeyBase58Check:  m0Pub,
  3153  			OperationType:                CreatorCoinOperationTypeSell,
  3154  			DeSoToSellNanos:              0,
  3155  			CreatorCoinToSellNanos:       464143,
  3156  			DeSoToAddNanos:               0,
  3157  			MinDeSoExpectedNanos:         0,
  3158  			MinCreatorCoinExpectedNanos:  0,
  3159  
  3160  			// These are the expectations
  3161  			CoinsInCirculationNanos: 4640969408,
  3162  			DeSoLockedNanos:         99960007,
  3163  			CoinWatermarkNanos:      4641433551,
  3164  			m0CCBalance:             0,
  3165  			m0HasPurchased:          false,
  3166  			m1CCBalance:             4640969408,
  3167  			m1HasPurchased:          true,
  3168  			m2CCBalance:             0,
  3169  			m2HasPurchased:          false,
  3170  			m0DeSoBalance:           6000029986,
  3171  			m1DeSoBalance:           5899999998,
  3172  			m2DeSoBalance:           6000000000,
  3173  		},
  3174  		// Have m1 buy more just up till CoinsInCirculationNanos is almost CoinWatermarkNanos
  3175  		// m0 should continue to receieve 1 basis point founders reward irrelevant of the CoinWatermarkNanos.
  3176  		{
  3177  			UpdaterPublicKeyBase58Check:  m1Pub,
  3178  			UpdaterPrivateKeyBase58Check: m1Priv,
  3179  			ProfilePublicKeyBase58Check:  m0Pub,
  3180  			OperationType:                CreatorCoinOperationTypeBuy,
  3181  			DeSoToSellNanos:              10000,
  3182  			CreatorCoinToSellNanos:       0,
  3183  			DeSoToAddNanos:               0,
  3184  			MinDeSoExpectedNanos:         0,
  3185  			MinCreatorCoinExpectedNanos:  0,
  3186  
  3187  			// These are the expectations
  3188  			CoinsInCirculationNanos: 4641124148,
  3189  			DeSoLockedNanos:         99970006,
  3190  			CoinWatermarkNanos:      4641433551,
  3191  			m0CCBalance:             15, // Notice how this is just barely above the autosell threshold.
  3192  			// If this was any smaller, this transaction would fail.
  3193  			m0HasPurchased: false,
  3194  			m1CCBalance:    4641124133,
  3195  			m1HasPurchased: true,
  3196  			m2CCBalance:    0,
  3197  			m2HasPurchased: false,
  3198  			m0DeSoBalance:  6000029986,
  3199  			m1DeSoBalance:  5899989996,
  3200  			m2DeSoBalance:  6000000000,
  3201  		},
  3202  		// Now we have m2 buy a tiny amount of m0
  3203  		// This should also mint m0 a tiny founders reward, but because m0's balance
  3204  		// is above the autosell threshold, any amount will suffice.
  3205  		{
  3206  			UpdaterPublicKeyBase58Check:  m2Pub,
  3207  			UpdaterPrivateKeyBase58Check: m2Priv,
  3208  			ProfilePublicKeyBase58Check:  m0Pub,
  3209  			OperationType:                CreatorCoinOperationTypeBuy,
  3210  			DeSoToSellNanos:              1000,
  3211  			CreatorCoinToSellNanos:       0,
  3212  			DeSoToAddNanos:               0,
  3213  			MinDeSoExpectedNanos:         0,
  3214  			MinCreatorCoinExpectedNanos:  0,
  3215  
  3216  			// These are the expectations
  3217  			CoinsInCirculationNanos: 4641139607,
  3218  			DeSoLockedNanos:         99971005,
  3219  			CoinWatermarkNanos:      4641433551,
  3220  			m0CCBalance:             16,
  3221  			m0HasPurchased:          false,
  3222  			m1CCBalance:             4641124133,
  3223  			m1HasPurchased:          true,
  3224  			m2CCBalance:             15458,
  3225  			m2HasPurchased:          true,
  3226  			m0DeSoBalance:           6000029986,
  3227  			m1DeSoBalance:           5899989996,
  3228  			m2DeSoBalance:           5999998998,
  3229  		},
  3230  	}
  3231  
  3232  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3233  }
  3234  
  3235  func TestCreatorCoinTinyFounderRewardBuySellAmounts_DeSoFounderReward(t *testing.T) {
  3236  	// Set up a blockchain
  3237  	assert := assert.New(t)
  3238  	require := require.New(t)
  3239  	_, _ = assert, require
  3240  
  3241  	creatorCoinTests := []*_CreatorCoinTestData{
  3242  		// Create a profile for m0
  3243  		{
  3244  			TxnType:                      TxnTypeUpdateProfile,
  3245  			UpdaterPublicKeyBase58Check:  m0Pub,
  3246  			UpdaterPrivateKeyBase58Check: m0Priv,
  3247  			ProfilePublicKeyBase58Check:  m0Pub,
  3248  			ProfileUsername:              "m0",
  3249  			ProfileDescription:           "i am m0",
  3250  			ProfilePic:                   "m0 profile pic",
  3251  			ProfileCreatorBasisPoints:    1,
  3252  			ProfileIsHidden:              false,
  3253  
  3254  			SkipChecks: true,
  3255  		},
  3256  		// Have m1 buy a large amount of m0 to push up the watermark
  3257  		{
  3258  			UpdaterPublicKeyBase58Check:  m1Pub,
  3259  			UpdaterPrivateKeyBase58Check: m1Priv,
  3260  			ProfilePublicKeyBase58Check:  m0Pub,
  3261  			OperationType:                CreatorCoinOperationTypeBuy,
  3262  			DeSoToSellNanos:              100000000,
  3263  			CreatorCoinToSellNanos:       0,
  3264  			DeSoToAddNanos:               0,
  3265  			MinDeSoExpectedNanos:         0,
  3266  			MinCreatorCoinExpectedNanos:  0,
  3267  
  3268  			// These are the expectations
  3269  			CoinsInCirculationNanos: 4641278831,
  3270  			DeSoLockedNanos:         99980001,
  3271  			CoinWatermarkNanos:      4641278831,
  3272  			m0CCBalance:             0,
  3273  			m0HasPurchased:          false,
  3274  			m1CCBalance:             4641278831,
  3275  			m1HasPurchased:          true,
  3276  			m2CCBalance:             0,
  3277  			m2HasPurchased:          false,
  3278  			m0DeSoBalance:           6000009997,
  3279  			m1DeSoBalance:           5899999998,
  3280  			m2DeSoBalance:           6000000000,
  3281  		},
  3282  		// Have m1 buy more just up till CoinsInCirculationNanos is almost CoinWatermarkNanos
  3283  		// m0 should continue to receieve 1 basis point founders reward irrelevant of the CoinWatermarkNanos.
  3284  		{
  3285  			UpdaterPublicKeyBase58Check:  m1Pub,
  3286  			UpdaterPrivateKeyBase58Check: m1Priv,
  3287  			ProfilePublicKeyBase58Check:  m0Pub,
  3288  			OperationType:                CreatorCoinOperationTypeBuy,
  3289  			DeSoToSellNanos:              10000,
  3290  			CreatorCoinToSellNanos:       0,
  3291  			DeSoToAddNanos:               0,
  3292  			MinDeSoExpectedNanos:         0,
  3293  			MinCreatorCoinExpectedNanos:  0,
  3294  
  3295  			// These are the expectations
  3296  			CoinsInCirculationNanos: 4641433550,
  3297  			DeSoLockedNanos:         99990000,
  3298  			CoinWatermarkNanos:      4641433550,
  3299  			m0CCBalance:             0,
  3300  			m0HasPurchased:          false,
  3301  			m1CCBalance:             4641433550,
  3302  			m1HasPurchased:          true,
  3303  			m2CCBalance:             0,
  3304  			m2HasPurchased:          false,
  3305  			m0DeSoBalance:           6000009997,
  3306  			m1DeSoBalance:           5899989996,
  3307  			m2DeSoBalance:           6000000000,
  3308  		},
  3309  		// Now we have m2 buy a tiny amount of m0
  3310  		// This should also mint m0 a tiny founders reward, but because m0's balance
  3311  		// is above the autosell threshold, any amount will suffice.
  3312  		{
  3313  			UpdaterPublicKeyBase58Check:  m2Pub,
  3314  			UpdaterPrivateKeyBase58Check: m2Priv,
  3315  			ProfilePublicKeyBase58Check:  m0Pub,
  3316  			OperationType:                CreatorCoinOperationTypeBuy,
  3317  			DeSoToSellNanos:              1000,
  3318  			CreatorCoinToSellNanos:       0,
  3319  			DeSoToAddNanos:               0,
  3320  			MinDeSoExpectedNanos:         0,
  3321  			MinCreatorCoinExpectedNanos:  0,
  3322  
  3323  			// These are the expectations
  3324  			CoinsInCirculationNanos: 4641449007,
  3325  			DeSoLockedNanos:         99990999,
  3326  			CoinWatermarkNanos:      4641449007,
  3327  			m0CCBalance:             0,
  3328  			m0HasPurchased:          false,
  3329  			m1CCBalance:             4641433550,
  3330  			m1HasPurchased:          true,
  3331  			m2CCBalance:             15457,
  3332  			m2HasPurchased:          true,
  3333  			m0DeSoBalance:           6000009997,
  3334  			m1DeSoBalance:           5899989996,
  3335  			m2DeSoBalance:           5999998998,
  3336  		},
  3337  	}
  3338  
  3339  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, true /*desoFounderReward*/)
  3340  }
  3341  
  3342  func TestCreatorCoinFullFounderRewardBuySellAmounts_CreatorCoinFounderReward(t *testing.T) {
  3343  	// Set up a blockchain
  3344  	assert := assert.New(t)
  3345  	require := require.New(t)
  3346  	_, _ = assert, require
  3347  
  3348  	creatorCoinTests := []*_CreatorCoinTestData{
  3349  		// Create a profile for m0
  3350  		{
  3351  			TxnType:                      TxnTypeUpdateProfile,
  3352  			UpdaterPublicKeyBase58Check:  m0Pub,
  3353  			UpdaterPrivateKeyBase58Check: m0Priv,
  3354  			ProfilePublicKeyBase58Check:  m0Pub,
  3355  			ProfileUsername:              "m0",
  3356  			ProfileDescription:           "i am m0",
  3357  			ProfilePic:                   "m0 profile pic",
  3358  			ProfileCreatorBasisPoints:    10000,
  3359  			ProfileIsHidden:              false,
  3360  
  3361  			SkipChecks: true,
  3362  		},
  3363  		// Have m1 buy a large amount of m0. It should all go to m0.
  3364  		{
  3365  			UpdaterPublicKeyBase58Check:  m1Pub,
  3366  			UpdaterPrivateKeyBase58Check: m1Priv,
  3367  			ProfilePublicKeyBase58Check:  m0Pub,
  3368  			OperationType:                CreatorCoinOperationTypeBuy,
  3369  			DeSoToSellNanos:              100000000,
  3370  			CreatorCoinToSellNanos:       0,
  3371  			DeSoToAddNanos:               0,
  3372  			MinDeSoExpectedNanos:         0,
  3373  			MinCreatorCoinExpectedNanos:  0,
  3374  
  3375  			// These are the expectations
  3376  			CoinsInCirculationNanos: 4641433551,
  3377  			DeSoLockedNanos:         99990000,
  3378  			CoinWatermarkNanos:      4641433551,
  3379  			m0CCBalance:             4641433551,
  3380  			m0HasPurchased:          false,
  3381  			m1CCBalance:             0,
  3382  			m1HasPurchased:          true, // Even though m1 does not received any creator coins, we set HasPurchased to true.
  3383  			m2CCBalance:             0,
  3384  			m2HasPurchased:          false,
  3385  			m0DeSoBalance:           5999999998,
  3386  			m1DeSoBalance:           5899999998,
  3387  			m2DeSoBalance:           6000000000,
  3388  		},
  3389  		// Have m0 sell. The DeSo should've effectively
  3390  		// been transferred from m1 to m0.
  3391  		{
  3392  			UpdaterPublicKeyBase58Check:  m0Pub,
  3393  			UpdaterPrivateKeyBase58Check: m0Priv,
  3394  			ProfilePublicKeyBase58Check:  m0Pub,
  3395  			OperationType:                CreatorCoinOperationTypeSell,
  3396  			DeSoToSellNanos:              0,
  3397  			CreatorCoinToSellNanos:       4641433551,
  3398  			DeSoToAddNanos:               0,
  3399  			MinDeSoExpectedNanos:         0,
  3400  			MinCreatorCoinExpectedNanos:  0,
  3401  
  3402  			// These are the expectations
  3403  			CoinsInCirculationNanos: 0,
  3404  			DeSoLockedNanos:         0,
  3405  			CoinWatermarkNanos:      4641433551,
  3406  			m0CCBalance:             0,
  3407  			m0HasPurchased:          false,
  3408  			m1CCBalance:             0,
  3409  			m1HasPurchased:          true, // Even though m1 does not received any creator coins, we set HasPurchased to true.
  3410  			m2CCBalance:             0,
  3411  			m2HasPurchased:          false,
  3412  			m0DeSoBalance:           6099979997,
  3413  			m1DeSoBalance:           5899999998,
  3414  			m2DeSoBalance:           6000000000,
  3415  		},
  3416  	}
  3417  
  3418  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3419  }
  3420  
  3421  func TestCreatorCoinLargeFounderRewardBuySellAmounts(t *testing.T) {
  3422  	// Set up a blockchain
  3423  	assert := assert.New(t)
  3424  	require := require.New(t)
  3425  	_, _ = assert, require
  3426  
  3427  	creatorCoinTests := []*_CreatorCoinTestData{
  3428  		// Create a profile for m0
  3429  		{
  3430  			TxnType:                      TxnTypeUpdateProfile,
  3431  			UpdaterPublicKeyBase58Check:  m0Pub,
  3432  			UpdaterPrivateKeyBase58Check: m0Priv,
  3433  			ProfilePublicKeyBase58Check:  m0Pub,
  3434  			ProfileUsername:              "m0",
  3435  			ProfileDescription:           "i am m0",
  3436  			ProfilePic:                   "m0 profile pic",
  3437  			ProfileCreatorBasisPoints:    9999,
  3438  			ProfileIsHidden:              false,
  3439  
  3440  			SkipChecks: true,
  3441  		},
  3442  		// Have m1 buy a huge amount of m0. This will move CoinWatermarkNanos up.
  3443  		{
  3444  			UpdaterPublicKeyBase58Check:  m1Pub,
  3445  			UpdaterPrivateKeyBase58Check: m1Priv,
  3446  			ProfilePublicKeyBase58Check:  m0Pub,
  3447  			OperationType:                CreatorCoinOperationTypeBuy,
  3448  			DeSoToSellNanos:              100000000,
  3449  			CreatorCoinToSellNanos:       0,
  3450  			DeSoToAddNanos:               0,
  3451  			MinDeSoExpectedNanos:         0,
  3452  			MinCreatorCoinExpectedNanos:  0,
  3453  
  3454  			// These are the expectations
  3455  			CoinsInCirculationNanos: 4641433551,
  3456  			DeSoLockedNanos:         99990000,
  3457  			CoinWatermarkNanos:      4641433551,
  3458  			m0CCBalance:             4640969407,
  3459  			m0HasPurchased:          false,
  3460  			m1CCBalance:             464144,
  3461  			m1HasPurchased:          true,
  3462  			m2CCBalance:             0,
  3463  			m2HasPurchased:          false,
  3464  			m0DeSoBalance:           5999999998,
  3465  			m1DeSoBalance:           5899999998,
  3466  			m2DeSoBalance:           6000000000,
  3467  		},
  3468  		// Have m2 try and buy a small amount of m0. If you set the amount
  3469  		// to 64000 DeSo nanos to sell, the amount to mint for m2 would
  3470  		// be 99 nano creator coins. This is below the autosell threshold,
  3471  		// so the buy (should) fail. It should respond with a rule error stating:
  3472  		// RuleErrorCreatorCoinBuyMustSatisfyAutoSellThresholdNanosForBuyer
  3473  		// Here it's set to 66000, minting just enough to push m2 above the threshold (103 nanos).
  3474  		{
  3475  			UpdaterPublicKeyBase58Check:  m2Pub,
  3476  			UpdaterPrivateKeyBase58Check: m2Priv,
  3477  			ProfilePublicKeyBase58Check:  m0Pub,
  3478  			OperationType:                CreatorCoinOperationTypeBuy,
  3479  			DeSoToSellNanos:              66000,
  3480  			CreatorCoinToSellNanos:       0,
  3481  			DeSoToAddNanos:               0,
  3482  			MinDeSoExpectedNanos:         0,
  3483  			MinCreatorCoinExpectedNanos:  0,
  3484  
  3485  			// These are the expectations
  3486  			CoinsInCirculationNanos: 4642454435,
  3487  			DeSoLockedNanos:         100055993,
  3488  			CoinWatermarkNanos:      4642454435,
  3489  			m0CCBalance:             4641990188,
  3490  			m0HasPurchased:          false,
  3491  			m1CCBalance:             464144,
  3492  			m1HasPurchased:          true,
  3493  			m2CCBalance:             103,
  3494  			m2HasPurchased:          true,
  3495  			m0DeSoBalance:           5999999998,
  3496  			m1DeSoBalance:           5899999998,
  3497  			m2DeSoBalance:           5999933998,
  3498  		},
  3499  	}
  3500  
  3501  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3502  }
  3503  
  3504  func TestCreatorCoinAroundThresholdBuySellAmounts(t *testing.T) {
  3505  	// Set up a blockchain
  3506  	assert := assert.New(t)
  3507  	require := require.New(t)
  3508  	_, _ = assert, require
  3509  
  3510  	creatorCoinTests := []*_CreatorCoinTestData{
  3511  		// Create a profile for m0
  3512  		{
  3513  			TxnType:                      TxnTypeUpdateProfile,
  3514  			UpdaterPublicKeyBase58Check:  m0Pub,
  3515  			UpdaterPrivateKeyBase58Check: m0Priv,
  3516  			ProfilePublicKeyBase58Check:  m0Pub,
  3517  			ProfileUsername:              "m0",
  3518  			ProfileDescription:           "i am m0",
  3519  			ProfilePic:                   "m0 profile pic",
  3520  			ProfileCreatorBasisPoints:    0,
  3521  			ProfileIsHidden:              false,
  3522  
  3523  			SkipChecks: true,
  3524  		},
  3525  		// Have m0 buy his a teeny amount of his own coins
  3526  		{
  3527  			UpdaterPublicKeyBase58Check:  m0Pub,
  3528  			UpdaterPrivateKeyBase58Check: m0Priv,
  3529  			ProfilePublicKeyBase58Check:  m0Pub,
  3530  			OperationType:                CreatorCoinOperationTypeBuy,
  3531  			DeSoToSellNanos:              7,
  3532  			CreatorCoinToSellNanos:       0,
  3533  			DeSoToAddNanos:               0,
  3534  			MinDeSoExpectedNanos:         0,
  3535  			MinCreatorCoinExpectedNanos:  0,
  3536  
  3537  			// These are the expectations
  3538  			CoinsInCirculationNanos: 18171213,
  3539  			DeSoLockedNanos:         6,
  3540  			CoinWatermarkNanos:      18171213,
  3541  			m0CCBalance:             18171213,
  3542  			m0HasPurchased:          true,
  3543  			m1CCBalance:             0,
  3544  			m1HasPurchased:          false,
  3545  			m2CCBalance:             0,
  3546  			m2HasPurchased:          false,
  3547  			m0DeSoBalance:           5999999989,
  3548  			m1DeSoBalance:           6000000000,
  3549  			m2DeSoBalance:           6000000000,
  3550  		},
  3551  		// m0 sells just enough creator coins to reach the CreatorCoinAutoSellThresholdNanos.
  3552  		// This should not completely sell the remaining holdings.
  3553  		{
  3554  			UpdaterPublicKeyBase58Check:  m0Pub,
  3555  			UpdaterPrivateKeyBase58Check: m0Priv,
  3556  			ProfilePublicKeyBase58Check:  m0Pub,
  3557  			OperationType:                CreatorCoinOperationTypeSell,
  3558  			DeSoToSellNanos:              0,
  3559  			CreatorCoinToSellNanos:       18171213 - DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos,
  3560  			DeSoToAddNanos:               0,
  3561  			MinDeSoExpectedNanos:         0,
  3562  			MinCreatorCoinExpectedNanos:  0,
  3563  
  3564  			// These are the expectations
  3565  			CoinsInCirculationNanos: DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos,
  3566  			DeSoLockedNanos:         0,
  3567  			CoinWatermarkNanos:      18171213,
  3568  			m0CCBalance:             DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos,
  3569  			m0HasPurchased:          true,
  3570  			m1CCBalance:             0,
  3571  			m1HasPurchased:          false,
  3572  			m2CCBalance:             0,
  3573  			m2HasPurchased:          false,
  3574  			m0DeSoBalance:           5999999992,
  3575  			m1DeSoBalance:           6000000000,
  3576  			m2DeSoBalance:           6000000000,
  3577  		},
  3578  		// m1 buys m0 increasing the total number of holders to 2.
  3579  		{
  3580  			UpdaterPublicKeyBase58Check:  m1Pub,
  3581  			UpdaterPrivateKeyBase58Check: m1Priv,
  3582  			ProfilePublicKeyBase58Check:  m0Pub,
  3583  			OperationType:                CreatorCoinOperationTypeBuy,
  3584  			DeSoToSellNanos:              1000,
  3585  			CreatorCoinToSellNanos:       0,
  3586  			DeSoToAddNanos:               0,
  3587  			MinDeSoExpectedNanos:         0,
  3588  			MinCreatorCoinExpectedNanos:  0,
  3589  
  3590  			// These are the expectations
  3591  			CoinsInCirculationNanos: 99966681,
  3592  			DeSoLockedNanos:         999,
  3593  			CoinWatermarkNanos:      99966681,
  3594  			m0CCBalance:             DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos,
  3595  			m0HasPurchased:          true,
  3596  			m1CCBalance:             99966671,
  3597  			m1HasPurchased:          true,
  3598  			m2CCBalance:             0,
  3599  			m2HasPurchased:          false,
  3600  			m0DeSoBalance:           5999999992,
  3601  			m1DeSoBalance:           5999998998,
  3602  			m2DeSoBalance:           6000000000,
  3603  		},
  3604  		// m0 sells a single nano of their own creator coin. This triggers the
  3605  		// CreatorCoinAutoSellThresholdNanos. This reduces the number of holders to 1.
  3606  		{
  3607  			UpdaterPublicKeyBase58Check:  m0Pub,
  3608  			UpdaterPrivateKeyBase58Check: m0Priv,
  3609  			ProfilePublicKeyBase58Check:  m0Pub,
  3610  			OperationType:                CreatorCoinOperationTypeSell,
  3611  			DeSoToSellNanos:              0,
  3612  			CreatorCoinToSellNanos:       1,
  3613  			DeSoToAddNanos:               0,
  3614  			MinDeSoExpectedNanos:         0,
  3615  			MinCreatorCoinExpectedNanos:  0,
  3616  
  3617  			// These are the expectations
  3618  			CoinsInCirculationNanos: 99966671,
  3619  			DeSoLockedNanos:         999,
  3620  			CoinWatermarkNanos:      99966681,
  3621  			m0CCBalance:             0,
  3622  			m0HasPurchased:          false,
  3623  			m1CCBalance:             99966671,
  3624  			m1HasPurchased:          true,
  3625  			m2CCBalance:             0,
  3626  			m2HasPurchased:          false,
  3627  			m0DeSoBalance:           5999999990,
  3628  			m1DeSoBalance:           5999998998,
  3629  			m2DeSoBalance:           6000000000,
  3630  		},
  3631  		// m2 now purchases m0's creator coins
  3632  		{
  3633  			UpdaterPublicKeyBase58Check:  m2Pub,
  3634  			UpdaterPrivateKeyBase58Check: m2Priv,
  3635  			ProfilePublicKeyBase58Check:  m0Pub,
  3636  			OperationType:                CreatorCoinOperationTypeBuy,
  3637  			DeSoToSellNanos:              1000000000,
  3638  			CreatorCoinToSellNanos:       0,
  3639  			DeSoToAddNanos:               0,
  3640  			MinDeSoExpectedNanos:         0,
  3641  			MinCreatorCoinExpectedNanos:  0,
  3642  
  3643  			// These are the expectations
  3644  			CoinsInCirculationNanos: 9999666925,
  3645  			DeSoLockedNanos:         999900999,
  3646  			CoinWatermarkNanos:      9999666925,
  3647  			m0CCBalance:             0,
  3648  			m0HasPurchased:          false,
  3649  			m1CCBalance:             99966671,
  3650  			m1HasPurchased:          true,
  3651  			m2CCBalance:             9899700254,
  3652  			m2HasPurchased:          true,
  3653  			m0DeSoBalance:           5999999990,
  3654  			m1DeSoBalance:           5999998998,
  3655  			m2DeSoBalance:           4999999998,
  3656  		},
  3657  		// m1 sells to just past the threshold, should trigger an autosell
  3658  		{
  3659  			UpdaterPublicKeyBase58Check:  m1Pub,
  3660  			UpdaterPrivateKeyBase58Check: m1Priv,
  3661  			ProfilePublicKeyBase58Check:  m0Pub,
  3662  			OperationType:                CreatorCoinOperationTypeSell,
  3663  			DeSoToSellNanos:              0,
  3664  			CreatorCoinToSellNanos:       99966671 - DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos + 1,
  3665  			DeSoToAddNanos:               0,
  3666  			MinDeSoExpectedNanos:         0,
  3667  			MinCreatorCoinExpectedNanos:  0,
  3668  
  3669  			// These are the expectations
  3670  			CoinsInCirculationNanos: 9899700254,
  3671  			DeSoLockedNanos:         970211757,
  3672  			CoinWatermarkNanos:      9999666925,
  3673  			m0CCBalance:             0,
  3674  			m0HasPurchased:          false,
  3675  			m1CCBalance:             0,
  3676  			m1HasPurchased:          false,
  3677  			m2CCBalance:             9899700254,
  3678  			m2HasPurchased:          true,
  3679  			m0DeSoBalance:           5999999990,
  3680  			m1DeSoBalance:           6029685269,
  3681  			m2DeSoBalance:           4999999998,
  3682  		},
  3683  		// m2 sells to just past the threshold, should trigger an autosell and clear the profile
  3684  		{
  3685  			UpdaterPublicKeyBase58Check:  m2Pub,
  3686  			UpdaterPrivateKeyBase58Check: m2Priv,
  3687  			ProfilePublicKeyBase58Check:  m0Pub,
  3688  			OperationType:                CreatorCoinOperationTypeSell,
  3689  			DeSoToSellNanos:              0,
  3690  			CreatorCoinToSellNanos:       9899700254 - DeSoMainnetParams.CreatorCoinAutoSellThresholdNanos + 1,
  3691  			DeSoToAddNanos:               0,
  3692  			MinDeSoExpectedNanos:         0,
  3693  			MinCreatorCoinExpectedNanos:  0,
  3694  
  3695  			// These are the expectations
  3696  			CoinsInCirculationNanos: 0,
  3697  			DeSoLockedNanos:         0,
  3698  			CoinWatermarkNanos:      9999666925,
  3699  			m0CCBalance:             0,
  3700  			m0HasPurchased:          false,
  3701  			m1CCBalance:             0,
  3702  			m1HasPurchased:          false,
  3703  			m2CCBalance:             0,
  3704  			m2HasPurchased:          false,
  3705  			m0DeSoBalance:           5999999990,
  3706  			m1DeSoBalance:           6029685269,
  3707  			m2DeSoBalance:           5970114731,
  3708  		},
  3709  	}
  3710  
  3711  	// These tests shoudl behave the same since there is no founder reward.
  3712  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3713  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, true /*desoFounderReward*/)
  3714  }
  3715  
  3716  // The salomon sequence is a sequence of transactions known to
  3717  // cause Bancor curve errors in the earlier days of the chain.
  3718  // The sequence is named after @salomon, the finder of the sequence.
  3719  func TestSalomonSequence(t *testing.T) {
  3720  	// Set up a blockchain
  3721  	assert := assert.New(t)
  3722  	require := require.New(t)
  3723  	_, _ = assert, require
  3724  
  3725  	creatorCoinTests := []*_CreatorCoinTestData{
  3726  		// Create a profile for m0. m0 represents salomon.
  3727  		{
  3728  			TxnType:                      TxnTypeUpdateProfile,
  3729  			UpdaterPublicKeyBase58Check:  m0Pub,
  3730  			UpdaterPrivateKeyBase58Check: m0Priv,
  3731  			ProfilePublicKeyBase58Check:  m0Pub,
  3732  			ProfileUsername:              "m0",
  3733  			ProfileDescription:           "i am m0",
  3734  			ProfilePic:                   "m0 profile pic",
  3735  			ProfileCreatorBasisPoints:    0,
  3736  			ProfileIsHidden:              false,
  3737  
  3738  			SkipChecks: true,
  3739  		},
  3740  		// m0 buys a specific amount of salomon
  3741  		// In the UI this would represent selling 323138431 nanos.
  3742  		{
  3743  			UpdaterPublicKeyBase58Check:  m0Pub,
  3744  			UpdaterPrivateKeyBase58Check: m0Priv,
  3745  			ProfilePublicKeyBase58Check:  m0Pub,
  3746  			OperationType:                CreatorCoinOperationTypeBuy,
  3747  			DeSoToSellNanos:              323106117 + 6,
  3748  			CreatorCoinToSellNanos:       0,
  3749  			DeSoToAddNanos:               0,
  3750  			MinDeSoExpectedNanos:         0,
  3751  			MinCreatorCoinExpectedNanos:  0,
  3752  
  3753  			// These are the expectations
  3754  			CoinsInCirculationNanos: 6861733544,
  3755  			DeSoLockedNanos:         323073812,
  3756  			CoinWatermarkNanos:      6861733544,
  3757  			m0CCBalance:             6861733544,
  3758  			m0HasPurchased:          true,
  3759  			m1CCBalance:             0,
  3760  			m1HasPurchased:          false,
  3761  			m2CCBalance:             0,
  3762  			m2HasPurchased:          false,
  3763  			m0DeSoBalance:           5676893873,
  3764  			m1DeSoBalance:           6000000000,
  3765  			m2DeSoBalance:           6000000000,
  3766  		},
  3767  		// m0 follows up with another specific purchase.
  3768  		// In the UI this represented selling 191807888 nanos.
  3769  		{
  3770  			UpdaterPublicKeyBase58Check:  m0Pub,
  3771  			UpdaterPrivateKeyBase58Check: m0Priv,
  3772  			ProfilePublicKeyBase58Check:  m0Pub,
  3773  			OperationType:                CreatorCoinOperationTypeBuy,
  3774  			DeSoToSellNanos:              191807888 + 6,
  3775  			CreatorCoinToSellNanos:       0,
  3776  			DeSoToAddNanos:               0,
  3777  			MinDeSoExpectedNanos:         0,
  3778  			MinCreatorCoinExpectedNanos:  0,
  3779  
  3780  			// These are the expectations
  3781  			CoinsInCirculationNanos: 8014879883,
  3782  			DeSoLockedNanos:         514862525,
  3783  			CoinWatermarkNanos:      8014879883,
  3784  			m0CCBalance:             8014879883,
  3785  			m0HasPurchased:          true,
  3786  			m1CCBalance:             0,
  3787  			m1HasPurchased:          false,
  3788  			m2CCBalance:             0,
  3789  			m2HasPurchased:          false,
  3790  			m0DeSoBalance:           5485085977,
  3791  			m1DeSoBalance:           6000000000,
  3792  			m2DeSoBalance:           6000000000,
  3793  		},
  3794  		// Now is where things got interesting. In the original salomon sequence,
  3795  		// the user (m0) attempted a max sell of all their creator coins. However,
  3796  		// due to some rounding error bugs this caused an abnormal reserve ratio
  3797  		// and the price quickly approached billions of USD / creator coins. Very
  3798  		// few creator coins were in circulation, and it would not have returned
  3799  		// to a normal price. Here we check that the amount is reset upon sale.
  3800  		{
  3801  			UpdaterPublicKeyBase58Check:  m0Pub,
  3802  			UpdaterPrivateKeyBase58Check: m0Priv,
  3803  			ProfilePublicKeyBase58Check:  m0Pub,
  3804  			OperationType:                CreatorCoinOperationTypeSell,
  3805  			DeSoToSellNanos:              0,
  3806  			CreatorCoinToSellNanos:       8014879883,
  3807  			DeSoToAddNanos:               0,
  3808  			MinDeSoExpectedNanos:         0,
  3809  			MinCreatorCoinExpectedNanos:  0,
  3810  
  3811  			// These are the expectations
  3812  			CoinsInCirculationNanos: 0,
  3813  			DeSoLockedNanos:         0,
  3814  			CoinWatermarkNanos:      8014879883,
  3815  			m0CCBalance:             0,
  3816  			m0HasPurchased:          false,
  3817  			m1CCBalance:             0,
  3818  			m1HasPurchased:          false,
  3819  			m2CCBalance:             0,
  3820  			m2HasPurchased:          false,
  3821  			m0DeSoBalance:           5999897012,
  3822  			m1DeSoBalance:           6000000000,
  3823  			m2DeSoBalance:           6000000000,
  3824  		},
  3825  	}
  3826  
  3827  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3828  }
  3829  
  3830  // This test stress-tests our Bancor equation by doing the smallest
  3831  // possible buy one can do, which utilizes the polynomial equation
  3832  // to bootstrap, and then doing a normal-sized buy
  3833  func TestCreatorCoinBigBuyAfterSmallBuy(t *testing.T) {
  3834  	// Set up a blockchain
  3835  	assert := assert.New(t)
  3836  	require := require.New(t)
  3837  	_, _ = assert, require
  3838  
  3839  	creatorCoinTests := []*_CreatorCoinTestData{
  3840  		// Create a profile for m0
  3841  		{
  3842  			TxnType:                      TxnTypeUpdateProfile,
  3843  			UpdaterPublicKeyBase58Check:  m0Pub,
  3844  			UpdaterPrivateKeyBase58Check: m0Priv,
  3845  			ProfilePublicKeyBase58Check:  m0Pub,
  3846  			ProfileUsername:              "m0",
  3847  			ProfileDescription:           "i am m0",
  3848  			ProfilePic:                   "m0 profile pic",
  3849  			ProfileCreatorBasisPoints:    2500,
  3850  			ProfileIsHidden:              false,
  3851  
  3852  			SkipChecks: true,
  3853  		},
  3854  		// Have m0 buy his a teeny amount of his own coins
  3855  		{
  3856  			UpdaterPublicKeyBase58Check:  m0Pub,
  3857  			UpdaterPrivateKeyBase58Check: m0Priv,
  3858  			ProfilePublicKeyBase58Check:  m0Pub,
  3859  			OperationType:                CreatorCoinOperationTypeBuy,
  3860  			DeSoToSellNanos:              2,
  3861  			CreatorCoinToSellNanos:       0,
  3862  			DeSoToAddNanos:               0,
  3863  			MinDeSoExpectedNanos:         0,
  3864  			MinCreatorCoinExpectedNanos:  0,
  3865  
  3866  			// These are the expectations
  3867  			CoinsInCirculationNanos: 10000004, // Something small
  3868  			DeSoLockedNanos:         1,
  3869  			CoinWatermarkNanos:      10000004, // Something small
  3870  			m0CCBalance:             10000004, // Something small
  3871  			m0HasPurchased:          true,
  3872  			m1CCBalance:             0,
  3873  			m1HasPurchased:          false,
  3874  			m2CCBalance:             0,
  3875  			m2HasPurchased:          false,
  3876  			m0DeSoBalance:           5999999994,
  3877  			m1DeSoBalance:           6000000000,
  3878  			m2DeSoBalance:           6000000000,
  3879  		},
  3880  		// Have m1 do a normal-sized buy of m0's coins
  3881  		{
  3882  			// These are the transaction params
  3883  			UpdaterPublicKeyBase58Check:  m1Pub,
  3884  			UpdaterPrivateKeyBase58Check: m1Priv,
  3885  			ProfilePublicKeyBase58Check:  m0Pub,
  3886  			OperationType:                CreatorCoinOperationTypeBuy,
  3887  			DeSoToSellNanos:              1271123456,
  3888  			CreatorCoinToSellNanos:       0,
  3889  			DeSoToAddNanos:               0,
  3890  			MinDeSoExpectedNanos:         0,
  3891  			MinCreatorCoinExpectedNanos:  0,
  3892  
  3893  			// These are the expectations
  3894  			CoinsInCirculationNanos: 10832149301,
  3895  			DeSoLockedNanos:         1270996344,
  3896  			CoinWatermarkNanos:      10832149301,
  3897  			m0CCBalance:             2715537328,
  3898  			m0HasPurchased:          true,
  3899  			m1CCBalance:             8116611973,
  3900  			m1HasPurchased:          true,
  3901  			m2CCBalance:             0,
  3902  			m2HasPurchased:          false,
  3903  			m0DeSoBalance:           5999999994,
  3904  			m1DeSoBalance:           4728876542,
  3905  			m2DeSoBalance:           6000000000,
  3906  		},
  3907  		// Have m0 sell their amount.
  3908  		{
  3909  			UpdaterPublicKeyBase58Check:  m0Pub,
  3910  			UpdaterPrivateKeyBase58Check: m0Priv,
  3911  			ProfilePublicKeyBase58Check:  m0Pub,
  3912  			OperationType:                CreatorCoinOperationTypeSell,
  3913  			DeSoToSellNanos:              0,
  3914  			CreatorCoinToSellNanos:       2715537328,
  3915  			DeSoToAddNanos:               0,
  3916  			MinDeSoExpectedNanos:         0,
  3917  			MinCreatorCoinExpectedNanos:  0,
  3918  
  3919  			// These are the expectations
  3920  			CoinsInCirculationNanos: 10832149301 - 2715537328,
  3921  			DeSoLockedNanos:         534717879,
  3922  			CoinWatermarkNanos:      10832149301,
  3923  			m0CCBalance:             0,
  3924  			m0HasPurchased:          false,
  3925  			m1CCBalance:             8116611973,
  3926  			m1HasPurchased:          true,
  3927  			m2CCBalance:             0,
  3928  			m2HasPurchased:          false,
  3929  			m0DeSoBalance:           6736204829,
  3930  			m1DeSoBalance:           4728876542,
  3931  			m2DeSoBalance:           6000000000,
  3932  		},
  3933  		// Have m1 sell their amount.
  3934  		{
  3935  			UpdaterPublicKeyBase58Check:  m1Pub,
  3936  			UpdaterPrivateKeyBase58Check: m1Priv,
  3937  			ProfilePublicKeyBase58Check:  m0Pub,
  3938  			OperationType:                CreatorCoinOperationTypeSell,
  3939  			DeSoToSellNanos:              0,
  3940  			CreatorCoinToSellNanos:       8116611973,
  3941  			DeSoToAddNanos:               0,
  3942  			MinDeSoExpectedNanos:         0,
  3943  			MinCreatorCoinExpectedNanos:  0,
  3944  
  3945  			// These are the expectations
  3946  			CoinsInCirculationNanos: 0,
  3947  			DeSoLockedNanos:         0,
  3948  			CoinWatermarkNanos:      10832149301,
  3949  			m0CCBalance:             0,
  3950  			m0HasPurchased:          false,
  3951  			m1CCBalance:             0,
  3952  			m1HasPurchased:          false,
  3953  			m2CCBalance:             0,
  3954  			m2HasPurchased:          false,
  3955  			m0DeSoBalance:           6736204829,
  3956  			m1DeSoBalance:           5263540947,
  3957  			m2DeSoBalance:           6000000000,
  3958  		},
  3959  	}
  3960  
  3961  	_helpTestCreatorCoinBuySell(t, creatorCoinTests, false)
  3962  }
  3963  
  3964  func TestCreatorCoinBigBigBuyBigSell(t *testing.T) {
  3965  	// Set up a blockchain
  3966  	assert := assert.New(t)
  3967  	require := require.New(t)
  3968  	_, _ = assert, require
  3969  
  3970  	desoToSellNanos := uint64(30000000000000000)
  3971  	{
  3972  		// Buy 30M DeSo worth of CC using polynomial model.
  3973  		polyMintedCCNanos := CalculateCreatorCoinToMintPolynomial(
  3974  			desoToSellNanos, 0, &DeSoMainnetParams)
  3975  
  3976  		// Sell half of the CC
  3977  		desoReturnedNanos := CalculateDeSoToReturn(
  3978  			polyMintedCCNanos/2, polyMintedCCNanos,
  3979  			desoToSellNanos, &DeSoMainnetParams)
  3980  
  3981  		// Sell the other half of the CC
  3982  		desoReturned2Nanos := CalculateDeSoToReturn(
  3983  			polyMintedCCNanos-polyMintedCCNanos/2, polyMintedCCNanos-polyMintedCCNanos/2,
  3984  			desoToSellNanos-desoReturnedNanos, &DeSoMainnetParams)
  3985  
  3986  		// Should get back the amount of DeSo we put in.
  3987  		require.Equal(desoToSellNanos, desoReturnedNanos+desoReturned2Nanos)
  3988  	}
  3989  
  3990  	{
  3991  		// Buy 30M worth of DeSo using the Bancor model at the very
  3992  		// beginning of the curve.
  3993  		// Sell the CC from the previous step down to zero.
  3994  		initialCCNanos := uint64(10000004)
  3995  		bancorMintedCCNanos := CalculateCreatorCoinToMintBancor(
  3996  			desoToSellNanos, initialCCNanos, 1, &DeSoMainnetParams)
  3997  
  3998  		// Sell half of the CC
  3999  		desoReturnedNanos := CalculateDeSoToReturn(
  4000  			bancorMintedCCNanos/2, bancorMintedCCNanos+initialCCNanos,
  4001  			desoToSellNanos+1, &DeSoMainnetParams)
  4002  
  4003  		// Sell the other half of the CC
  4004  		desoReturned2Nanos := CalculateDeSoToReturn(
  4005  			bancorMintedCCNanos-bancorMintedCCNanos/2,
  4006  			bancorMintedCCNanos-bancorMintedCCNanos/2+initialCCNanos,
  4007  			desoToSellNanos-desoReturnedNanos+1, &DeSoMainnetParams)
  4008  
  4009  		// Should get back the amount of DeSo we put in.
  4010  		require.Equal(int64(desoToSellNanos), int64(desoReturnedNanos+desoReturned2Nanos))
  4011  	}
  4012  }
  4013  
  4014  func _creatorCoinTxn(t *testing.T, chain *Blockchain, db *badger.DB,
  4015  	params *DeSoParams, feeRateNanosPerKB uint64,
  4016  	UpdaterPublicKeyBase58Check string,
  4017  	UpdaterPrivateKeyBase58Check string,
  4018  	// See CreatorCoinMetadataa for an explanation of these fields.
  4019  	ProfilePublicKeyBase58Check string,
  4020  	OperationType CreatorCoinOperationType,
  4021  	DeSoToSellNanos uint64,
  4022  	CreatorCoinToSellNanos uint64,
  4023  	DeSoToAddNanos uint64,
  4024  	MinDeSoExpectedNanos uint64,
  4025  	MinCreatorCoinExpectedNanos uint64) (
  4026  	_utxoOps []*UtxoOperation, _txn *MsgDeSoTxn, _height uint32, _err error) {
  4027  
  4028  	assert := assert.New(t)
  4029  	require := require.New(t)
  4030  	_ = assert
  4031  	_ = require
  4032  
  4033  	updaterPkBytes, _, err := Base58CheckDecode(UpdaterPublicKeyBase58Check)
  4034  	require.NoError(err)
  4035  
  4036  	profilePkBytes, _, err := Base58CheckDecode(ProfilePublicKeyBase58Check)
  4037  	require.NoError(err)
  4038  
  4039  	utxoView, err := NewUtxoView(db, params, nil)
  4040  	require.NoError(err)
  4041  
  4042  	txn, totalInputMake, changeAmountMake, feesMake, err := chain.CreateCreatorCoinTxn(
  4043  		updaterPkBytes,
  4044  		profilePkBytes,
  4045  		OperationType,
  4046  		DeSoToSellNanos,
  4047  		CreatorCoinToSellNanos,
  4048  		DeSoToAddNanos,
  4049  		MinDeSoExpectedNanos,
  4050  		MinCreatorCoinExpectedNanos,
  4051  		feeRateNanosPerKB,
  4052  		nil, /*mempool*/
  4053  		[]*DeSoOutput{})
  4054  
  4055  	if err != nil {
  4056  		return nil, nil, 0, err
  4057  	}
  4058  
  4059  	if OperationType == CreatorCoinOperationTypeBuy {
  4060  		require.Equal(int64(totalInputMake), int64(changeAmountMake+feesMake+DeSoToSellNanos))
  4061  	} else {
  4062  		require.Equal(int64(totalInputMake), int64(changeAmountMake+feesMake))
  4063  	}
  4064  
  4065  	// Sign the transaction now that its inputs are set up.
  4066  	_signTxn(t, txn, UpdaterPrivateKeyBase58Check)
  4067  
  4068  	txHash := txn.Hash()
  4069  	// Always use height+1 for validation since it's assumed the transaction will
  4070  	// get mined into the next block.
  4071  	blockHeight := chain.blockTip().Height + 1
  4072  	utxoOps, totalInput, totalOutput, fees, err :=
  4073  		utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  4074  	// ConnectTransaction should treat the amount locked as contributing to the
  4075  	// output.
  4076  	if err != nil {
  4077  		return nil, nil, 0, err
  4078  	}
  4079  	require.Equal(totalInput, totalOutput+fees)
  4080  	require.GreaterOrEqual(totalInput, totalInputMake)
  4081  
  4082  	// We should have one SPEND UtxoOperation for each input, one ADD operation
  4083  	// for each output, and one OperationTypeCreatorCoin operation at the end.
  4084  	numInputs := len(txn.TxInputs)
  4085  	numOps := len(utxoOps)
  4086  	for ii := 0; ii < numInputs; ii++ {
  4087  		require.Equal(OperationTypeSpendUtxo, utxoOps[ii].Type)
  4088  	}
  4089  	for ii := numInputs; ii < numOps-1; ii++ {
  4090  		require.Equal(OperationTypeAddUtxo, utxoOps[ii].Type)
  4091  	}
  4092  	require.Equal(OperationTypeCreatorCoin, utxoOps[numOps-1].Type)
  4093  
  4094  	require.NoError(utxoView.FlushToDb())
  4095  
  4096  	return utxoOps, txn, blockHeight, nil
  4097  }
  4098  
  4099  func _creatorCoinTxnWithTestMeta(
  4100  	testMeta *TestMeta,
  4101  	feeRateNanosPerKB uint64,
  4102  	UpdaterPublicKeyBase58Check string,
  4103  	UpdaterPrivateKeyBase58Check string,
  4104  	// See CreatorCoinMetadataa for an explanation of these fields.
  4105  	ProfilePublicKeyBase58Check string,
  4106  	OperationType CreatorCoinOperationType,
  4107  	DeSoToSellNanos uint64,
  4108  	CreatorCoinToSellNanos uint64,
  4109  	DeSoToAddNanos uint64,
  4110  	MinDeSoExpectedNanos uint64,
  4111  	MinCreatorCoinExpectedNanos uint64) {
  4112  
  4113  	testMeta.expectedSenderBalances = append(
  4114  		testMeta.expectedSenderBalances, _getBalance(testMeta.t, testMeta.chain, nil, UpdaterPublicKeyBase58Check))
  4115  
  4116  	currentOps, currentTxn, _, err := _creatorCoinTxn(
  4117  		testMeta.t, testMeta.chain, testMeta.db, testMeta.params,
  4118  		feeRateNanosPerKB, UpdaterPublicKeyBase58Check,
  4119  		UpdaterPrivateKeyBase58Check, ProfilePublicKeyBase58Check, OperationType,
  4120  		DeSoToSellNanos, CreatorCoinToSellNanos, DeSoToAddNanos,
  4121  		MinDeSoExpectedNanos, MinCreatorCoinExpectedNanos)
  4122  
  4123  	require.NoError(testMeta.t, err)
  4124  	testMeta.txnOps = append(testMeta.txnOps, currentOps)
  4125  	testMeta.txns = append(testMeta.txns, currentTxn)
  4126  }
  4127  
  4128  func _doCreatorCoinTransferTxnWithDiamonds(t *testing.T, chain *Blockchain, db *badger.DB,
  4129  	params *DeSoParams, feeRateNanosPerKB uint64,
  4130  	SenderPublicKeyBase58Check string,
  4131  	SenderPrivBase58Check string,
  4132  	ReceiverPublicKeyBase58Check string,
  4133  	DiamondPostHash *BlockHash,
  4134  	DiamondLevel int64) (
  4135  	_utxoOps []*UtxoOperation, _txn *MsgDeSoTxn, _height uint32, _err error) {
  4136  
  4137  	assert := assert.New(t)
  4138  	require := require.New(t)
  4139  	_ = assert
  4140  	_ = require
  4141  
  4142  	senderPkBytes, _, err := Base58CheckDecode(SenderPublicKeyBase58Check)
  4143  	require.NoError(err)
  4144  
  4145  	receiverPkBytes, _, err := Base58CheckDecode(ReceiverPublicKeyBase58Check)
  4146  	require.NoError(err)
  4147  
  4148  	utxoView, err := NewUtxoView(db, params, nil)
  4149  	require.NoError(err)
  4150  
  4151  	txn, totalInputMake, _, _, err := chain.CreateCreatorCoinTransferTxnWithDiamonds(
  4152  		senderPkBytes,
  4153  		receiverPkBytes,
  4154  		DiamondPostHash,
  4155  		DiamondLevel,
  4156  		feeRateNanosPerKB, nil, []*DeSoOutput{})
  4157  	if err != nil {
  4158  		return nil, nil, 0, err
  4159  	}
  4160  
  4161  	// Sign the transaction now that its inputs are set up.
  4162  	_signTxn(t, txn, SenderPrivBase58Check)
  4163  
  4164  	txHash := txn.Hash()
  4165  	// Always use height+1 for validation since it's assumed the transaction will
  4166  	// get mined into the next block.
  4167  	blockHeight := chain.blockTip().Height + 1
  4168  	utxoOps, totalInput, totalOutput, fees, err :=
  4169  		utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  4170  	// ConnectTransaction should treat the amount locked as contributing to the
  4171  	// output.
  4172  	if err != nil {
  4173  		return nil, nil, 0, err
  4174  	}
  4175  	require.Equal(totalInput, totalOutput+fees)
  4176  	require.GreaterOrEqual(totalInput, totalInputMake)
  4177  
  4178  	// We should have one SPEND UtxoOperation for each input, one ADD operation
  4179  	// for each output, and one OperationTypeCreatorCoinTransfer operation at the end.
  4180  	require.Equal(len(txn.TxInputs)+len(txn.TxOutputs)+1, len(utxoOps))
  4181  	for ii := 0; ii < len(txn.TxInputs); ii++ {
  4182  		require.Equal(OperationTypeSpendUtxo, utxoOps[ii].Type)
  4183  	}
  4184  	require.Equal(OperationTypeCreatorCoinTransfer, utxoOps[len(utxoOps)-1].Type)
  4185  
  4186  	require.NoError(utxoView.FlushToDb())
  4187  
  4188  	return utxoOps, txn, blockHeight, nil
  4189  }
  4190  
  4191  func _doCreatorCoinTransferTxn(t *testing.T, chain *Blockchain, db *badger.DB,
  4192  	params *DeSoParams, feeRateNanosPerKB uint64,
  4193  	UpdaterPublicKeyBase58Check string, UpdaterPrivateKeyBase58Check string,
  4194  	// See CreatorCoinTransferMetadataa for an explanation of these fields.
  4195  	ProfilePublicKeyBase58Check string,
  4196  	ReceiverPublicKeyBase58Check string,
  4197  	CreatorCoinToTransferNanos uint64) (
  4198  	_utxoOps []*UtxoOperation, _txn *MsgDeSoTxn, _height uint32, _err error) {
  4199  
  4200  	assert := assert.New(t)
  4201  	require := require.New(t)
  4202  	_ = assert
  4203  	_ = require
  4204  
  4205  	updaterPkBytes, _, err := Base58CheckDecode(UpdaterPublicKeyBase58Check)
  4206  	require.NoError(err)
  4207  
  4208  	profilePkBytes, _, err := Base58CheckDecode(ProfilePublicKeyBase58Check)
  4209  	require.NoError(err)
  4210  
  4211  	receiverPkBytes, _, err := Base58CheckDecode(ReceiverPublicKeyBase58Check)
  4212  	require.NoError(err)
  4213  
  4214  	utxoView, err := NewUtxoView(db, params, nil)
  4215  	require.NoError(err)
  4216  
  4217  	txn, totalInputMake, _, _, err := chain.CreateCreatorCoinTransferTxn(
  4218  		updaterPkBytes,
  4219  		profilePkBytes,
  4220  		CreatorCoinToTransferNanos,
  4221  		receiverPkBytes,
  4222  		feeRateNanosPerKB,
  4223  		nil, /*mempool*/
  4224  		[]*DeSoOutput{})
  4225  	if err != nil {
  4226  		return nil, nil, 0, err
  4227  	}
  4228  
  4229  	// Sign the transaction now that its inputs are set up.
  4230  	_signTxn(t, txn, UpdaterPrivateKeyBase58Check)
  4231  
  4232  	txHash := txn.Hash()
  4233  	// Always use height+1 for validation since it's assumed the transaction will
  4234  	// get mined into the next block.
  4235  	blockHeight := chain.blockTip().Height + 1
  4236  	utxoOps, totalInput, totalOutput, fees, err :=
  4237  		utxoView.ConnectTransaction(txn, txHash, getTxnSize(*txn), blockHeight, true /*verifySignature*/, false /*ignoreUtxos*/)
  4238  	// ConnectTransaction should treat the amount locked as contributing to the
  4239  	// output.
  4240  	if err != nil {
  4241  		return nil, nil, 0, err
  4242  	}
  4243  	require.Equal(totalInput, totalOutput+fees)
  4244  	require.Equal(totalInput, totalInputMake)
  4245  
  4246  	// We should have one SPEND UtxoOperation for each input, one ADD operation
  4247  	// for each output, and one OperationTypeCreatorCoinTransfer operation at the end.
  4248  	require.Equal(len(txn.TxInputs)+len(txn.TxOutputs)+1, len(utxoOps))
  4249  	for ii := 0; ii < len(txn.TxInputs); ii++ {
  4250  		require.Equal(OperationTypeSpendUtxo, utxoOps[ii].Type)
  4251  	}
  4252  	require.Equal(OperationTypeCreatorCoinTransfer, utxoOps[len(utxoOps)-1].Type)
  4253  
  4254  	require.NoError(utxoView.FlushToDb())
  4255  
  4256  	return utxoOps, txn, blockHeight, nil
  4257  }