Skip to content

Commit

Permalink
Preventing user from paying hub if channel is not in open state (#349)
Browse files Browse the repository at this point in the history
* Preventing user from paying hub if channel is not in open state

* Fixed block address input unit test
  • Loading branch information
nephix authored Sep 26, 2019
1 parent c6ce813 commit 97268ff
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 25 deletions.
12 changes: 11 additions & 1 deletion raiden-dapp/src/components/AddressInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ export default class AddressInput extends Mixins(BlockieMixin) {
})
exclude!: Array<string>;
@Prop({
default: function() {
return [''];
}
})
block!: Array<string>;
address: string = '';
valid: boolean = false;
Expand Down Expand Up @@ -106,6 +113,10 @@ export default class AddressInput extends Mixins(BlockieMixin) {
this.errorMessages.push(this.$t(
'address-input.error.invalid-excluded-address'
) as string);
} else if (this.block.includes(value)) {
this.errorMessages.push(this.$t(
'address-input.error.channel-not-open'
) as string);
} else if (
AddressUtils.isAddress(value) &&
!AddressUtils.checkAddressChecksum(value)
Expand Down Expand Up @@ -247,7 +258,6 @@ export default class AddressInput extends Mixins(BlockieMixin) {
line-height: 16px;
.v-messages__wrapper {
height: 25px;
display: flex;
flex-direction: column;
align-items: start;
Expand Down
3 changes: 2 additions & 1 deletion raiden-dapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"no-checksum": "Please enter an address in checksum format. You can convert your address on https://ethsum.netlify.com",
"empty": "Please enter an address or ENS name",
"ens-resolve-failed": "Please enter a resolvable ENS name",
"invalid-excluded-address": "Please enter a different address or ENS name. You can't use your own address or the address of the token network."
"invalid-excluded-address": "Please enter a different address or ENS name. You can't use your own address or the address of the token network.",
"channel-not-open": "Please enter a hub address you have an open channel with."
}
},
"amount-input": {
Expand Down
13 changes: 11 additions & 2 deletions raiden-dapp/src/views/Payment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<address-input
v-model="target"
:exclude="[token.address, defaultAccount]"
:block="blockedHubs"
></address-input>
</v-flex>
</v-layout>
Expand Down Expand Up @@ -115,7 +116,7 @@ import ActionButton from '@/components/ActionButton.vue';
import ChannelDeposit from '@/components/ChannelDeposit.vue';
import { BigNumber } from 'ethers/utils';
import { mapGetters, mapState } from 'vuex';
import { RaidenChannel } from 'raiden-ts';
import { RaidenChannel, ChannelState } from 'raiden-ts';
import { Zero } from 'ethers/constants';
@Component({
Expand All @@ -131,7 +132,7 @@ import { Zero } from 'ethers/constants';
},
computed: {
...mapState(['defaultAccount']),
...mapGetters(['channelWithBiggestCapacity'])
...mapGetters(['channelWithBiggestCapacity', 'channels'])
}
})
export default class Payment extends Vue {
Expand All @@ -147,10 +148,18 @@ export default class Payment extends Vue {
errorTitle: string = '';
error: string = '';
channels!: (tokenAddress: string) => RaidenChannel[];
channelWithBiggestCapacity!: (
tokenAddress: string
) => RaidenChannel | undefined;
get blockedHubs(): string[] {
return this.channels(this.token.address)
.filter((channel: RaidenChannel) => channel.state !== ChannelState.open)
.map((channel: RaidenChannel) => channel.partner as string);
}
get capacity(): BigNumber {
const withBiggestCapacity = this.channelWithBiggestCapacity(
this.token.address
Expand Down
23 changes: 17 additions & 6 deletions raiden-dapp/tests/unit/components/address-input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ describe('AddressInput', function() {
let wrapper: Wrapper<AddressInput>;
let raiden: Mocked<RaidenService>;
let mockIdenticon: jest.Mock<any, any>;
const excludedAddress: string = '0x65E84e07dD79F3f03d72bc0fab664F56E6C55909';
const excludeAddress: string = '0x65E84e07dD79F3f03d72bc0fab664F56E6C55909';
const blockAddress: string = '0x123456789009876543211234567890';

beforeEach(() => {
mockIdenticon = jest.fn().mockResolvedValue('');
raiden = new RaidenService(store) as Mocked<RaidenService>;
wrapper = mount(AddressInput, {
propsData: {
value: '',
exclude: [excludedAddress]
exclude: [excludeAddress],
block: [blockAddress]
},
mocks: {
$raiden: raiden,
Expand Down Expand Up @@ -156,9 +158,9 @@ describe('AddressInput', function() {
});
});

describe('excluded', () => {
describe('exclude & block address', () => {
it('should show error message if excluded address is entered', async () => {
mockInput(wrapper, excludedAddress);
mockInput(wrapper, excludeAddress);
await wrapper.vm.$nextTick();

const messages = wrapper.find('.v-messages__message');
Expand All @@ -168,7 +170,16 @@ describe('AddressInput', function() {
);
});

it('should not show error message if there is no exclude prop', async () => {
it('should show error message if blocked address is entered', async () => {
mockInput(wrapper, blockAddress);
await wrapper.vm.$nextTick();

const messages = wrapper.find('.v-messages__message');
expect(messages.exists()).toBe(true);
expect(messages.text()).toBe('address-input.error.channel-not-open');
});

it('should not show error message if there is no exclude or block prop', async () => {
wrapper = mount(AddressInput, {
propsData: {
value: ''
Expand All @@ -182,7 +193,7 @@ describe('AddressInput', function() {
}
});

mockInput(wrapper, excludedAddress);
mockInput(wrapper, excludeAddress);
await wrapper.vm.$nextTick();

const messages = wrapper.find('.v-messages__message');
Expand Down
33 changes: 18 additions & 15 deletions raiden-dapp/tests/unit/views/payment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ describe('Payment.vue', () => {
name: 'Test Token'
};

const channel = {
capacity: One,
balance: Zero,
ownDeposit: One,
partnerDeposit: Zero,
partner: '0xaddr' as any,
token: '0xtoken' as any,
state: ChannelState.open,
settleTimeout: 500,
tokenNetwork: '0xtokennetwork' as any,
closeBlock: undefined,
openBlock: 12346,
id: 1
} as RaidenChannel;

function vueFactory(
router: VueRouter,
raiden: RaidenService
Expand All @@ -54,21 +69,9 @@ describe('Payment.vue', () => {
vuetify,
store: new Store({
getters: {
channelWithBiggestCapacity: jest.fn().mockReturnValue(() => ({
capacity: One,
balance: Zero,
ownDeposit: One,
partnerDeposit: Zero,
partner: '0xaddr' as any,
token: '0xtoken' as any,
state: ChannelState.open,
settleTimeout: 500,
tokenNetwork: '0xtokennetwork' as any,
closeBlock: undefined,
openBlock: 12346,
id: 1
})),
defaultAddress: jest.fn().mockReturnValue(['0x1234567890'])
channelWithBiggestCapacity: jest.fn().mockReturnValue(() => channel),
defaultAddress: jest.fn().mockReturnValue(['0x1234567890']),
channels: jest.fn().mockReturnValue(() => [channel])
}
}),
mocks: {
Expand Down

0 comments on commit 97268ff

Please sign in to comment.