github.com/algorand/go-algorand-sdk@v1.24.0/future/atomicTransactionComposer_test.go (about)

     1  package future
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/algorand/go-algorand-sdk/abi"
     7  	"github.com/algorand/go-algorand-sdk/crypto"
     8  	"github.com/algorand/go-algorand-sdk/types"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestMakeAtomicTransactionComposer(t *testing.T) {
    13  	var atc AtomicTransactionComposer
    14  	require.Equal(t, atc.GetStatus(), BUILDING)
    15  	require.Equal(t, atc.Count(), 0)
    16  	copyAtc := atc.Clone()
    17  	require.Equal(t, atc, copyAtc)
    18  }
    19  
    20  func TestAddTransaction(t *testing.T) {
    21  	var atc AtomicTransactionComposer
    22  	account := crypto.GenerateAccount()
    23  	txSigner := BasicAccountTransactionSigner{Account: account}
    24  
    25  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
    26  	require.NoError(t, err)
    27  
    28  	tx := types.Transaction{
    29  		Type: types.PaymentTx,
    30  		Header: types.Header{
    31  			Sender:     addr,
    32  			Fee:        217000,
    33  			FirstValid: 972508,
    34  			LastValid:  973508,
    35  			Note:       []byte{180, 81, 121, 57, 252, 250, 210, 113},
    36  			GenesisID:  "testnet-v31.0",
    37  		},
    38  		PaymentTxnFields: types.PaymentTxnFields{
    39  			Receiver: addr,
    40  			Amount:   5000,
    41  		},
    42  	}
    43  
    44  	txAndSigner := TransactionWithSigner{
    45  		Txn:    tx,
    46  		Signer: txSigner,
    47  	}
    48  
    49  	err = atc.AddTransaction(txAndSigner)
    50  	require.NoError(t, err)
    51  
    52  	require.Equal(t, atc.GetStatus(), BUILDING)
    53  	require.Equal(t, atc.Count(), 1)
    54  }
    55  
    56  func TestAddTransactionWhenNotBuilding(t *testing.T) {
    57  	var atc AtomicTransactionComposer
    58  	account := crypto.GenerateAccount()
    59  	txSigner := BasicAccountTransactionSigner{Account: account}
    60  
    61  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
    62  	require.NoError(t, err)
    63  
    64  	tx := types.Transaction{
    65  		Type: types.PaymentTx,
    66  		Header: types.Header{
    67  			Sender:     addr,
    68  			Fee:        217000,
    69  			FirstValid: 972508,
    70  			LastValid:  973508,
    71  			Note:       []byte{180, 81, 121, 57, 252, 250, 210, 113},
    72  			GenesisID:  "testnet-v31.0",
    73  		},
    74  		PaymentTxnFields: types.PaymentTxnFields{
    75  			Receiver: addr,
    76  			Amount:   5000,
    77  		},
    78  	}
    79  
    80  	txAndSigner := TransactionWithSigner{
    81  		Txn:    tx,
    82  		Signer: txSigner,
    83  	}
    84  
    85  	err = atc.AddTransaction(txAndSigner)
    86  	require.NoError(t, err)
    87  
    88  	_, err = atc.BuildGroup()
    89  	require.NoError(t, err)
    90  	require.Equal(t, atc.GetStatus(), BUILT)
    91  
    92  	err = atc.AddTransaction(txAndSigner)
    93  	require.Error(t, err)
    94  }
    95  
    96  func TestAddTransactionWithMaxTransactions(t *testing.T) {
    97  	var atc AtomicTransactionComposer
    98  	account := crypto.GenerateAccount()
    99  	txSigner := BasicAccountTransactionSigner{Account: account}
   100  
   101  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
   102  	require.NoError(t, err)
   103  
   104  	tx := types.Transaction{
   105  		Type: types.PaymentTx,
   106  		Header: types.Header{
   107  			Sender:     addr,
   108  			Fee:        217000,
   109  			FirstValid: 972508,
   110  			LastValid:  973508,
   111  			Note:       []byte{180, 81, 121, 57, 252, 250, 210, 113},
   112  			GenesisID:  "testnet-v31.0",
   113  		},
   114  		PaymentTxnFields: types.PaymentTxnFields{
   115  			Receiver: addr,
   116  			Amount:   5000,
   117  		},
   118  	}
   119  
   120  	txAndSigner := TransactionWithSigner{
   121  		Txn:    tx,
   122  		Signer: txSigner,
   123  	}
   124  
   125  	for i := 0; i < 16; i++ {
   126  		err = atc.AddTransaction(txAndSigner)
   127  		require.NoError(t, err)
   128  	}
   129  
   130  	require.Equal(t, atc.GetStatus(), BUILDING)
   131  	require.Equal(t, atc.Count(), 16)
   132  
   133  	err = atc.AddTransaction(txAndSigner)
   134  	require.Error(t, err)
   135  }
   136  
   137  func TestAddMethodCall(t *testing.T) {
   138  	var atc AtomicTransactionComposer
   139  	account := crypto.GenerateAccount()
   140  	txSigner := BasicAccountTransactionSigner{Account: account}
   141  	methodSig := "add()uint32"
   142  
   143  	method, err := abi.MethodFromSignature(methodSig)
   144  	require.NoError(t, err)
   145  
   146  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
   147  	require.NoError(t, err)
   148  
   149  	err = atc.AddMethodCall(
   150  		AddMethodCallParams{
   151  			AppID:  4,
   152  			Method: method,
   153  			Sender: addr,
   154  			Signer: txSigner,
   155  		})
   156  	require.NoError(t, err)
   157  	require.Equal(t, atc.GetStatus(), BUILDING)
   158  	require.Equal(t, atc.Count(), 1)
   159  }
   160  
   161  func TestAddMethodCallWithManualForeignArgs(t *testing.T) {
   162  	var atc AtomicTransactionComposer
   163  	account := crypto.GenerateAccount()
   164  	txSigner := BasicAccountTransactionSigner{Account: account}
   165  	methodSig := "add(application)uint32"
   166  
   167  	method, err := abi.MethodFromSignature(methodSig)
   168  	require.NoError(t, err)
   169  
   170  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
   171  	require.NoError(t, err)
   172  
   173  	arg_addr_str := "E4VCHISDQPLIZWMALIGNPK2B2TERPDMR64MZJXE3UL75MUDXZMADX5OWXM"
   174  	arg_addr, err := types.DecodeAddress(arg_addr_str)
   175  	require.NoError(t, err)
   176  
   177  	params := AddMethodCallParams{
   178  		AppID:           4,
   179  		Method:          method,
   180  		Sender:          addr,
   181  		Signer:          txSigner,
   182  		MethodArgs:      []interface{}{2},
   183  		ForeignApps:     []uint64{1},
   184  		ForeignAssets:   []uint64{5},
   185  		ForeignAccounts: []string{arg_addr_str},
   186  	}
   187  	err = atc.AddMethodCall(params)
   188  	require.NoError(t, err)
   189  	require.Equal(t, atc.GetStatus(), BUILDING)
   190  	require.Equal(t, atc.Count(), 1)
   191  	txns, err := atc.BuildGroup()
   192  	require.NoError(t, err)
   193  
   194  	require.Equal(t, len(txns[0].Txn.ForeignApps), 2)
   195  	require.Equal(t, txns[0].Txn.ForeignApps[0], types.AppIndex(1))
   196  	require.Equal(t, txns[0].Txn.ForeignApps[1], types.AppIndex(2))
   197  	// verify original params object hasn't changed.
   198  	require.Equal(t, params.ForeignApps, []uint64{1})
   199  
   200  	require.Equal(t, len(txns[0].Txn.ForeignAssets), 1)
   201  	require.Equal(t, txns[0].Txn.ForeignAssets[0], types.AssetIndex(5))
   202  
   203  	require.Equal(t, len(txns[0].Txn.Accounts), 1)
   204  	require.Equal(t, txns[0].Txn.Accounts[0], arg_addr)
   205  }
   206  
   207  func TestGatherSignatures(t *testing.T) {
   208  	var atc AtomicTransactionComposer
   209  	account := crypto.GenerateAccount()
   210  	txSigner := BasicAccountTransactionSigner{Account: account}
   211  
   212  	addr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA")
   213  	require.NoError(t, err)
   214  
   215  	tx := types.Transaction{
   216  		Type: types.PaymentTx,
   217  		Header: types.Header{
   218  			Sender:     addr,
   219  			Fee:        217000,
   220  			FirstValid: 972508,
   221  			LastValid:  973508,
   222  			Note:       []byte{180, 81, 121, 57, 252, 250, 210, 113},
   223  			GenesisID:  "testnet-v31.0",
   224  		},
   225  		PaymentTxnFields: types.PaymentTxnFields{
   226  			Receiver: addr,
   227  			Amount:   5000,
   228  		},
   229  	}
   230  
   231  	txAndSigner := TransactionWithSigner{
   232  		Txn:    tx,
   233  		Signer: txSigner,
   234  	}
   235  
   236  	err = atc.AddTransaction(txAndSigner)
   237  	require.NoError(t, err)
   238  	require.Equal(t, atc.GetStatus(), BUILDING)
   239  	require.Equal(t, atc.Count(), 1)
   240  
   241  	sigs, err := atc.GatherSignatures()
   242  	require.NoError(t, err)
   243  	require.Equal(t, atc.GetStatus(), SIGNED)
   244  	require.Equal(t, len(sigs), 1)
   245  
   246  	txWithSigners, _ := atc.BuildGroup()
   247  	require.Equal(t, types.Digest{}, txWithSigners[0].Txn.Group)
   248  
   249  	_, expectedSig, err := crypto.SignTransaction(account.PrivateKey, tx)
   250  	require.NoError(t, err)
   251  	require.Equal(t, len(sigs[0]), len(expectedSig))
   252  	require.Equal(t, sigs[0], expectedSig)
   253  }