github.com/koko1123/flow-go-1@v0.29.6/cmd/util/ledger/reporters/fungible_token_tracker_test.go (about)

     1  package reporters_test
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/onflow/cadence"
    11  	jsoncdc "github.com/onflow/cadence/encoding/json"
    12  	"github.com/rs/zerolog"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/koko1123/flow-go-1/cmd/util/ledger/reporters"
    16  	"github.com/koko1123/flow-go-1/fvm"
    17  	"github.com/koko1123/flow-go-1/fvm/derived"
    18  	"github.com/koko1123/flow-go-1/fvm/utils"
    19  	"github.com/koko1123/flow-go-1/ledger"
    20  	"github.com/koko1123/flow-go-1/model/flow"
    21  	"github.com/koko1123/flow-go-1/utils/unittest"
    22  )
    23  
    24  func TestFungibleTokenTracker(t *testing.T) {
    25  
    26  	// bootstrap ledger
    27  	payloads := []ledger.Payload{}
    28  	chain := flow.Testnet.Chain()
    29  	view := utils.NewSimpleViewFromPayloads(payloads)
    30  
    31  	vm := fvm.NewVirtualMachine()
    32  	derivedBlockData := derived.NewEmptyDerivedBlockData()
    33  	opts := []fvm.Option{
    34  		fvm.WithChain(chain),
    35  		fvm.WithAuthorizationChecksEnabled(false),
    36  		fvm.WithSequenceNumberCheckAndIncrementEnabled(false),
    37  		fvm.WithDerivedBlockData(derivedBlockData),
    38  	}
    39  	ctx := fvm.NewContext(opts...)
    40  	bootstrapOptions := []fvm.BootstrapProcedureOption{
    41  		fvm.WithTransactionFee(fvm.DefaultTransactionFees),
    42  		fvm.WithAccountCreationFee(fvm.DefaultAccountCreationFee),
    43  		fvm.WithMinimumStorageReservation(fvm.DefaultMinimumStorageReservation),
    44  		fvm.WithStorageMBPerFLOW(fvm.DefaultStorageMBPerFLOW),
    45  		fvm.WithInitialTokenSupply(unittest.GenesisTokenSupply),
    46  	}
    47  
    48  	err := vm.Run(ctx, fvm.Bootstrap(unittest.ServiceAccountPublicKey, bootstrapOptions...), view)
    49  	require.NoError(t, err)
    50  
    51  	// deploy wrapper resource
    52  	testContract := fmt.Sprintf(`
    53  	import FungibleToken from 0x%s
    54  
    55  	pub contract WrappedToken {
    56  		pub resource WrappedVault {
    57  			pub var vault: @FungibleToken.Vault
    58  
    59  			init(v: @FungibleToken.Vault) {
    60  				self.vault <- v
    61  			}
    62  			destroy() {
    63  			  destroy self.vault
    64  			}
    65  		}
    66  		pub fun CreateWrappedVault(inp: @FungibleToken.Vault): @WrappedToken.WrappedVault {
    67  			return <-create WrappedVault(v :<- inp)
    68  		}
    69  	}`, fvm.FungibleTokenAddress(chain))
    70  
    71  	deployingTestContractScript := []byte(fmt.Sprintf(`
    72  	transaction {
    73  		prepare(signer: AuthAccount) {
    74  				signer.contracts.add(name: "%s", code: "%s".decodeHex())
    75  		}
    76  	}
    77  	`, "WrappedToken", hex.EncodeToString([]byte(testContract))))
    78  
    79  	txBody := flow.NewTransactionBody().
    80  		SetScript(deployingTestContractScript).
    81  		AddAuthorizer(chain.ServiceAddress())
    82  
    83  	tx := fvm.Transaction(txBody, derivedBlockData.NextTxIndexForTestingOnly())
    84  	err = vm.Run(ctx, tx, view)
    85  	require.NoError(t, err)
    86  	require.NoError(t, tx.Err)
    87  
    88  	wrapTokenScript := []byte(fmt.Sprintf(`
    89  							import FungibleToken from 0x%s
    90  							import FlowToken from 0x%s
    91  							import WrappedToken from 0x%s
    92  
    93  							transaction(amount: UFix64) {
    94  								prepare(signer: AuthAccount) {
    95  									let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault)
    96  										?? panic("Could not borrow reference to the owner's Vault!")
    97  
    98  									let sentVault <- vaultRef.withdraw(amount: amount)
    99  									let wrappedFlow <- WrappedToken.CreateWrappedVault(inp :<- sentVault)
   100  									signer.save(<-wrappedFlow, to: /storage/wrappedToken)
   101  								}
   102  							}`, fvm.FungibleTokenAddress(chain), fvm.FlowTokenAddress(chain), chain.ServiceAddress()))
   103  
   104  	txBody = flow.NewTransactionBody().
   105  		SetScript(wrapTokenScript).
   106  		AddArgument(jsoncdc.MustEncode(cadence.UFix64(105))).
   107  		AddAuthorizer(chain.ServiceAddress())
   108  
   109  	tx = fvm.Transaction(txBody, derivedBlockData.NextTxIndexForTestingOnly())
   110  	err = vm.Run(ctx, tx, view)
   111  	require.NoError(t, err)
   112  	require.NoError(t, tx.Err)
   113  
   114  	dir := t.TempDir()
   115  	log := zerolog.Nop()
   116  	reporterFactory := reporters.NewReportFileWriterFactory(dir, log)
   117  
   118  	br := reporters.NewFungibleTokenTracker(log, reporterFactory, chain, []string{reporters.FlowTokenTypeID(chain)})
   119  	err = br.Report(view.Payloads(), ledger.State{})
   120  	require.NoError(t, err)
   121  
   122  	data, err := os.ReadFile(reporterFactory.Filename(reporters.FungibleTokenTrackerReportPrefix))
   123  	require.NoError(t, err)
   124  
   125  	// wrappedToken
   126  	require.True(t, strings.Contains(string(data), `{"path":"storage/wrappedToken/vault","address":"8c5303eaa26202d6","balance":105,"type_id":"A.7e60df042a9c0868.FlowToken.Vault"}`))
   127  	// flowTokenVaults
   128  	require.True(t, strings.Contains(string(data), `{"path":"storage/flowTokenVault","address":"8c5303eaa26202d6","balance":99999999999699895,"type_id":"A.7e60df042a9c0868.FlowToken.Vault"}`))
   129  	require.True(t, strings.Contains(string(data), `{"path":"storage/flowTokenVault","address":"9a0766d93b6608b7","balance":100000,"type_id":"A.7e60df042a9c0868.FlowToken.Vault"}`))
   130  	require.True(t, strings.Contains(string(data), `{"path":"storage/flowTokenVault","address":"7e60df042a9c0868","balance":100000,"type_id":"A.7e60df042a9c0868.FlowToken.Vault"}`))
   131  	require.True(t, strings.Contains(string(data), `{"path":"storage/flowTokenVault","address":"912d5440f7e3769e","balance":100000,"type_id":"A.7e60df042a9c0868.FlowToken.Vault"}`))
   132  
   133  	// do not remove this line, see https://github.com/koko1123/flow-go-1/pull/2237
   134  	t.Log("success")
   135  }