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 }