Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

MixinTransaction Unit Tests #2069

Conversation

jalextowle
Copy link
Contributor

Description

This PR introduces unit tests for the MixinTransaction contract.

Testing instructions

yarn build:contracts && yarn test:contracts && yarn lint:contracts

Types of changes

  • Unit Tests

Checklist:

  • Prefix PR title with [WIP] if necessary.
  • Add tests to cover changes as needed.
  • Update documentation as needed.
  • Add new entries to the relevant CHANGELOG.jsons.

@jalextowle jalextowle force-pushed the feature/contracts/3.0/transaction-units branch 3 times, most recently from 9276787 to 3c9333c Compare August 15, 2019 22:50
@jalextowle jalextowle marked this pull request as ready for review August 16, 2019 00:17
@jalextowle jalextowle force-pushed the feature/contracts/3.0/transaction-units branch from a09c654 to fb41818 Compare August 20, 2019 23:13
@jalextowle jalextowle requested a review from moodlezoup August 20, 2019 23:16
@jalextowle jalextowle force-pushed the feature/contracts/3.0/transaction-units branch from 0761efe to ea950a5 Compare August 21, 2019 00:22
@abandeali1 abandeali1 mentioned this pull request Aug 21, 2019
4 tasks
Copy link
Contributor

@dorothy-zbornak dorothy-zbornak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty clean overall! Nice job.

I wonder if it's worthwhile to have a test case where signature validation fails on an inner transaction, maybe just to assert that we do check signatures on inner transactions. I think this is a possible scenario, right?

@@ -567,7 +577,10 @@ workflows:
# - build-website:
# requires:
# - build
- test-contracts-ganache-3.0:
- test-exchange-ganache-3.0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever girl

return expect(tx).to.revertWith(expectedError);
});

it('should revert if the same transaction is executed twice in a batch', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


// Duplicate the first transaction. This should cause the call to `batchExecuteTransactions()` to fail
// because this transaction will have the same order hash as transaction1.
const transaction2 = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just set transaction2 = transaction1?

'0x0000000000000000000000000000000000000000000000000000000000000020'.concat(
encodedDeadbeef.slice(2, encodedDeadbeef.length),
),
).to.be.true();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not expect(result[0]).to.eq('0x00...'.concat(...)) so we can see the actual vs expected if it fails?

expect(result.length).to.be.eq(2);
expect(
result[0] ===
'0x0000000000000000000000000000000000000000000000000000000000000020'.concat(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's probably worth it to refactor this encoding logic out, for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. My rationale for not doing this is that a fix to the AbiEncoder will actually allow us to use that for this check. At the moment, I have to do this because AbiEncoder.create('bytes').decode(result[0]) will not correctly decode the bytes (it will actually just return the 32 byte slot containing the length). I've added an Asana backlog task for this, so it should actually be completed at some point. What do you think of this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's a hassle, nbd.

const validSignature = randomSignature();

const currentTimestamp = await getLatestBlockTimestampAsync();
const transaction1 = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call these txs something like innerTx and outerTx?


// Use the transaction in execute transaction.
await expect(
transactionsContract.executeTransaction.sendTransactionAsync(transaction, validSignature),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This technically doesn't wait for the tx to be mined (even though it's probably all the same on ganache).

Suggested change
transactionsContract.executeTransaction.sendTransactionAsync(transaction, validSignature),
transactionsContract.executeTransaction.awaitTransactionSuccessAsync(transaction, validSignature),

There's a couple other spots where this is done, too.

const currentTimestamp = await getLatestBlockTimestampAsync();
const transaction = {
...EMPTY_ZERO_EX_TRANSACTION,
expirationTimeSeconds: new BigNumber(currentTimestamp).plus(10),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting a little repetitive. How about having EMPTY_ZERO_EX_TRANSACTION hold some timestamp in the distant future? Like new BigNumber(Math.floor(_.now() / 1000) + 86400).

const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);

// Verify that the returndata of the transaction is 0xDEADBEEF
const result = await transactionsContract.executeTransaction.callAsync(transaction, validSignature, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TransactionHelper class in @0x/contracts-test-utils might reduce some of the code in blocks where you do a callAsync, sendTransactionAsync, and getTxWithDecodedLogsAsync since it does all three.

public
returns (bytes memory)
{
emit ExecutableCalled(data, returnData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be super cool to log the current context address, too.

@jalextowle jalextowle closed this Aug 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants