Skip to content

Commit

Permalink
Merge pull request #15 from decentraland/feat/better-transaction-life…
Browse files Browse the repository at this point in the history
…cycle

feat: better transaction lifecycle
  • Loading branch information
nicosantangelo authored Sep 21, 2018
2 parents 3d53434 + 3be4653 commit 5c2c39a
Show file tree
Hide file tree
Showing 9 changed files with 533 additions and 173 deletions.
231 changes: 127 additions & 104 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@types/mocha": "^5.2.5",
"chai": "^4.1.2",
"dcl-tslint-config-standard": "^1.0.1",
"decentraland-eth": "^4.2.0",
"decentraland-eth": "^5.0.0",
"decentraland-ui": "^1.8.0",
"husky": "^0.14.3",
"mocha": "^5.2.0",
Expand All @@ -57,7 +57,7 @@
"validate-commit-message": "^3.0.1"
},
"peerDependencies": {
"decentraland-eth": ">=4.2.0",
"decentraland-eth": ">=5.0.0",
"decentraland-ui": "^1.8.0",
"react": "^16.4.1",
"react-redux": "^5.0.7",
Expand Down
8 changes: 7 additions & 1 deletion src/modules/storage/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
import {
FETCH_TRANSACTION_REQUEST,
FETCH_TRANSACTION_SUCCESS,
FETCH_TRANSACTION_FAILURE
FETCH_TRANSACTION_FAILURE,
UPDATE_TRANSACTION_STATUS,
UPDATE_TRANSACTION_NONCE,
REPLACE_TRANSACTION_SUCCESS
} from '../transaction/actions'

const disabledLoad = (store: any) =>
Expand Down Expand Up @@ -51,6 +54,9 @@ export function createStorageMiddleware<T>(options: StorageMiddleware<T>) {
FETCH_TRANSACTION_REQUEST,
FETCH_TRANSACTION_SUCCESS,
FETCH_TRANSACTION_FAILURE,
UPDATE_TRANSACTION_STATUS,
UPDATE_TRANSACTION_NONCE,
REPLACE_TRANSACTION_SUCCESS,
...actions
]
)
Expand Down
81 changes: 75 additions & 6 deletions src/modules/transaction/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AnyAction } from 'redux'
import { action } from 'typesafe-actions'
import { Transaction } from './types'
import { txUtils } from 'decentraland-eth'

// Fetch transaction

Expand All @@ -23,12 +24,14 @@ export const fetchTransactionSuccess = (transaction: Transaction) =>
action(FETCH_TRANSACTION_SUCCESS, { transaction })

export const fetchTransactionFailure = (
transaction: Transaction,
error: string
hash: string,
status: txUtils.Transaction['type'],
message: string
) =>
action(FETCH_TRANSACTION_FAILURE, {
transaction,
error
hash,
status,
message
})

export type FetchTransactionRequestAction = ReturnType<
Expand All @@ -43,11 +46,77 @@ export type FetchTransactionFailureAction = ReturnType<

// Watch pending transactions

export const WATCH_PENDING_TRANSACTIONS = 'Watch pending transactions'
export const WATCH_PENDING_TRANSACTIONS = 'Watch Pending Transactions'

export const watchPendingTransactions = () =>
action(WATCH_PENDING_TRANSACTIONS, {})

export type WatchPendingTransactionsAction = ReturnType<
typeof fetchTransactionFailure
typeof watchPendingTransactions
>

// Update transaction status

export const UPDATE_TRANSACTION_STATUS = 'Update Transaction Status'

export const updateTransactionStatus = (
hash: string,
status: txUtils.Transaction['type'] | null
) => action(UPDATE_TRANSACTION_STATUS, { hash, status })

export type UpdateTransactionStatusAction = ReturnType<
typeof updateTransactionStatus
>

// Update transaction nonce

export const UPDATE_TRANSACTION_NONCE = 'Update Transaction Nonce'

export const updateTransactionNonce = (hash: string, nonce: number) =>
action(UPDATE_TRANSACTION_NONCE, { hash, nonce })

export type UpdateTransactionNonceAction = ReturnType<
typeof updateTransactionNonce
>

// Watch dropped transactions

export const WATCH_DROPPED_TRANSACTIONS = 'Watch Dropped Transactions'

export const watchDroppedTransactions = () =>
action(WATCH_DROPPED_TRANSACTIONS, {})

export type WatchDroppedTransactionsAction = ReturnType<
typeof watchDroppedTransactions
>

// Replace transaction

export const REPLACE_TRANSACTION_REQUEST = '[Request] Replace Transaction'
export const REPLACE_TRANSACTION_SUCCESS = '[Success] Replace Transaction'
export const REPLACE_TRANSACTION_FAILURE = '[Failure] Replace Transaction'

export const replaceTransactionRequest = (hash: string, nonce: number) =>
action(REPLACE_TRANSACTION_REQUEST, {
hash,
nonce
})

export const replaceTransactionSuccess = (hash: string, replaceBy: string) =>
action(REPLACE_TRANSACTION_SUCCESS, { hash, replaceBy })

export const replaceTransactionFailure = (hash: string, error: string) =>
action(REPLACE_TRANSACTION_FAILURE, {
hash,
error
})

export type ReplaceTransactionRequestAction = ReturnType<
typeof replaceTransactionRequest
>
export type ReplaceTransactionSuccessAction = ReturnType<
typeof replaceTransactionSuccess
>
export type ReplaceTransactionFailureAction = ReturnType<
typeof replaceTransactionFailure
>
81 changes: 70 additions & 11 deletions src/modules/transaction/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TransactionStatus, Transaction } from './types'
import { Transaction } from './types'
import { getTransactionFromAction } from './utils'
import { loadingReducer, LoadingState } from '../loading/reducer'
import {
Expand All @@ -7,8 +7,15 @@ import {
FetchTransactionFailureAction,
FETCH_TRANSACTION_REQUEST,
FETCH_TRANSACTION_SUCCESS,
FETCH_TRANSACTION_FAILURE
FETCH_TRANSACTION_FAILURE,
UPDATE_TRANSACTION_STATUS,
UpdateTransactionStatusAction,
UPDATE_TRANSACTION_NONCE,
UpdateTransactionNonceAction,
REPLACE_TRANSACTION_SUCCESS,
ReplaceTransactionSuccessAction
} from './actions'
import { txUtils } from 'decentraland-eth'

export type TransactionState = {
data: Transaction[]
Expand All @@ -26,6 +33,9 @@ export type TransactionReducerAction =
| FetchTransactionRequestAction
| FetchTransactionSuccessAction
| FetchTransactionFailureAction
| UpdateTransactionStatusAction
| UpdateTransactionNonceAction
| ReplaceTransactionSuccessAction

export function transactionReducer(
state = INITIAL_STATE,
Expand All @@ -45,7 +55,10 @@ export function transactionReducer(
timestamp: Date.now(),
from: action.payload.address,
actionType: actionRef.type,
status: TransactionStatus.Pending
// these always start as null, and they get updated by the saga
status: null,
nonce: null,
replacedBy: null
}
]
}
Expand All @@ -61,32 +74,78 @@ export function transactionReducer(
actionTransaction.hash === transaction.hash
? {
...transaction,
...actionTransaction,
status: TransactionStatus.Confirmed
...actionTransaction
}
: transaction
)
}
}
case FETCH_TRANSACTION_FAILURE: {
const actionTransaction = action.payload.transaction
const { hash, status, message } = action.payload
return {
loading: loadingReducer(state.loading, action),
error: action.payload.error,
error: message,
data: state.data.map(
(transaction: Transaction) =>
// prettier-ignore
actionTransaction.hash === transaction.hash
hash === transaction.hash
? {
...transaction,
...actionTransaction,
status: TransactionStatus.Failed,
error: action.payload.error
status
}
: transaction
)
}
}
case UPDATE_TRANSACTION_STATUS: {
return {
loading: loadingReducer(state.loading, action),
error: null,
data: state.data.map(
(transaction: Transaction) =>
// prettier-ignore
action.payload.hash === transaction.hash
? {
...transaction,
status: action.payload.status
}
: transaction
)
}
}
case UPDATE_TRANSACTION_NONCE: {
return {
loading: loadingReducer(state.loading, action),
error: null,
data: state.data.map(
(transaction: Transaction) =>
// prettier-ignore
action.payload.hash === transaction.hash
? {
...transaction,
nonce: action.payload.nonce
}
: transaction
)
}
}
case REPLACE_TRANSACTION_SUCCESS: {
return {
loading: loadingReducer(state.loading, action),
error: null,
data: state.data.map(
(transaction: Transaction) =>
// prettier-ignore
action.payload.hash === transaction.hash
? {
...transaction,
status: txUtils.TRANSACTION_TYPES.replaced,
replacedBy: action.payload.replaceBy
}
: transaction
)
}
}
default:
return state
}
Expand Down
Loading

0 comments on commit 5c2c39a

Please sign in to comment.