StakeTokensMapper implements StatefulActionToParticleGroupsMapper<StakeTokensAction> { @Override public List<ParticleGroup> mapToParticleGroups(StakeTokensAction stake, Stream<Particle> store) throws StageActionException { final RRI tokenRef = stake.getRRI(); List<SpunParticle> particles = new ArrayList<>(); Map<? extends Class<? extends Particle>, List<Particle>> inputParticlesByClass = store .collect(Collectors.groupingBy(Particle::getClass)); RegisteredValidatorParticle delegate = inputParticlesByClass .getOrDefault(RegisteredValidatorParticle.class, ImmutableList.of()) .stream() .map(RegisteredValidatorParticle.class::cast) .findFirst() .orElseThrow(() -> StakeNotPossibleException.notRegistered(stake.getDelegate())); if (!delegate.allowsDelegator(stake.getFrom())) { throw StakeNotPossibleException.notAllowed(delegate.getAddress(), stake.getFrom()); } RegisteredValidatorParticle newDelegate = delegate.copyWithNonce(delegate.getNonce() + 1); particles.add(SpunParticle.down(delegate)); particles.add(SpunParticle.up(newDelegate)); List<TransferrableTokensParticle> stakeConsumables = inputParticlesByClass .getOrDefault(TransferrableTokensParticle.class, ImmutableList.of()) .stream() .map(TransferrableTokensParticle.class::cast) .filter(p -> p.getTokenDefinitionReference().equals(tokenRef)) .collect(Collectors.toList()); try { particles.addAll(mapToParticles(stake, stakeConsumables)); } catch (NotEnoughFungiblesException e) { throw new InsufficientFundsException( tokenRef, TokenUnitConversions.subunitsToUnits(e.getCurrent()), stake.getAmount() ); } System.out.println(stake); particles.forEach(sp -> System.out.println(sp.getSpin() + " " + sp.getParticle())); return Collections.singletonList( ParticleGroup.of(particles) ); } StakeTokensMapper(); @Override Set<ShardedParticleStateId> requiredState(StakeTokensAction action); @Override List<ParticleGroup> mapToParticleGroups(StakeTokensAction stake, Stream<Particle> store);  }
@Test public void when_staking_tokens_with_funds_against_unregistered_delegate__then_error_is_thrown() { RadixAddress address1 = RadixAddress.from("JEbhKQzBn4qJzWJFBbaPioA2GTeaQhuUjYWkanTE6N8VvvPpvM8"); RadixAddress delegate = RadixAddress.from("23B6fH3FekJeP6e5guhZAk6n9z4fmTo5Tngo3a11Wg5R8gsWTV2x"); RRI token = RRI.of(address1, "COOKIE"); StakeTokensAction action = mock(StakeTokensAction.class); when(action.getAmount()).thenReturn(new BigDecimal(1)); when(action.getFrom()).thenReturn(address1); when(action.getRRI()).thenReturn(token); when(action.getDelegate()).thenReturn(delegate); StakeTokensMapper mapper = new StakeTokensMapper(); Stream<Particle> particles = Stream.of( new TransferrableTokensParticle( UInt256.MAX_VALUE, UInt256.ONE, address1, 0, token, ImmutableMap.of() ) ); assertThatThrownBy(() -> mapper.mapToParticleGroups(action, particles)) .isInstanceOf(StakeNotPossibleException.class); }
@Test public void when_staking_tokens_with_funds__then_error_is_not_thrown() { RadixAddress address1 = RadixAddress.from("JEbhKQzBn4qJzWJFBbaPioA2GTeaQhuUjYWkanTE6N8VvvPpvM8"); RadixAddress delegate = RadixAddress.from("23B6fH3FekJeP6e5guhZAk6n9z4fmTo5Tngo3a11Wg5R8gsWTV2x"); RRI token = RRI.of(address1, "COOKIE"); StakeTokensAction action = mock(StakeTokensAction.class); when(action.getAmount()).thenReturn(new BigDecimal(1)); when(action.getFrom()).thenReturn(address1); when(action.getRRI()).thenReturn(token); when(action.getDelegate()).thenReturn(delegate); StakeTokensMapper mapper = new StakeTokensMapper(); Stream<Particle> particles = Stream.of( new RegisteredValidatorParticle( delegate, 0 ), new TransferrableTokensParticle( UInt256.MAX_VALUE, UInt256.ONE, address1, 0, token, ImmutableMap.of() ) ); mapper.mapToParticleGroups(action, particles); }