Skip to content

Commit

Permalink
Handle invalid fulfillments
Browse files Browse the repository at this point in the history
  • Loading branch information
sappenin committed Dec 17, 2024
1 parent 570dc6b commit 5b60fd1
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,24 @@ static XrpCurrencyAmount computeFee(
Objects.requireNonNull(currentLedgerBaseFeeDrops);
Objects.requireNonNull(fulfillment);

final int fulfillmentByteSize = Base64.getUrlDecoder().decode(
((PreimageSha256Fulfillment) fulfillment).getEncodedPreimage()
).length;
final int baseFee = currentLedgerBaseFeeDrops.value().intValue();
if (PreimageSha256Fulfillment.class.isAssignableFrom(fulfillment.getClass())) {

// See https://xrpl.org/docs/references/protocol/transactions/types/escrowfinish#escrowfinish-fields for '
// computing the additional fee for Escrows.
// In particular: `extraFee = view.fees().base * (32 + (fb->size() / 16))`
// See https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp#L368
final int extraFeeDrops = baseFee * (32 + (fulfillmentByteSize / 16));
final int totalFeeDrops = baseFee + extraFeeDrops; // <-- Add an extra base fee
return XrpCurrencyAmount.of(
UnsignedLong.valueOf(totalFeeDrops)
);
final long fulfillmentByteSize = Base64.getUrlDecoder().decode(
((PreimageSha256Fulfillment) fulfillment).getEncodedPreimage()
).length;
// See https://xrpl.org/docs/references/protocol/transactions/types/escrowfinish#escrowfinish-fields for '
// computing the additional fee for Escrows.
// In particular: `extraFee = view.fees().base * (32 + (fb->size() / 16))`
// See https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp#L368
final long baseFee = currentLedgerBaseFeeDrops.value().longValue();
final long extraFeeDrops = baseFee * (32 + (fulfillmentByteSize / 16));
final long totalFeeDrops = baseFee + extraFeeDrops; // <-- Add an extra base fee
return XrpCurrencyAmount.of(
UnsignedLong.valueOf(totalFeeDrops)
);
} else {
throw new RuntimeException("Only PreimageSha256Fulfillment is supported.");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.io.BaseEncoding;
Expand All @@ -30,6 +31,7 @@
import com.ripple.cryptoconditions.CryptoConditionReader;
import com.ripple.cryptoconditions.CryptoConditionWriter;
import com.ripple.cryptoconditions.Fulfillment;
import com.ripple.cryptoconditions.PrefixSha256Fulfillment;
import com.ripple.cryptoconditions.PreimageSha256Condition;
import com.ripple.cryptoconditions.PreimageSha256Fulfillment;
import com.ripple.cryptoconditions.der.DerEncodingException;
Expand Down Expand Up @@ -421,4 +423,47 @@ public void testNormalizeWithVariousFulfillmentSizes(int numBytes, int baseFee,
);
assertThat(computedFee).isEqualTo(XrpCurrencyAmount.ofDrops(expectedDrops));
}

@Test
public void testComputeFeeWithWrongFulfillment() {
//////////////////////
// Invalid Fulfillment
//////////////////////

PreimageSha256Fulfillment preimageSha256Fulfillment = PreimageSha256Fulfillment.from(new byte[10]);
PrefixSha256Fulfillment prefixFulfillment = PrefixSha256Fulfillment.from(
new byte[1], 50, preimageSha256Fulfillment
);
Exception thrownException = assertThrows(
Exception.class, () -> EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), prefixFulfillment)
);
assertThat(thrownException instanceof RuntimeException).isTrue();
assertThat(thrownException.getMessage()).isEqualTo("Only PreimageSha256Fulfillment is supported.");
}

@Test
public void testComputeFeeWithNullParams() {
PreimageSha256Fulfillment preimageSha256Fulfillment = PreimageSha256Fulfillment.from(new byte[10]);
PrefixSha256Fulfillment prefixFulfillment = PrefixSha256Fulfillment.from(
new byte[1], 50, preimageSha256Fulfillment
);

//////////////////////
// Null Base Fee
//////////////////////
Exception thrownException = assertThrows(
Exception.class, () -> EscrowFinish.computeFee(null, prefixFulfillment)
);
assertThat(thrownException instanceof NullPointerException).isTrue();
assertThat(thrownException.getMessage()).isNull();

//////////////////////
// Null Fulfillment
//////////////////////
thrownException = assertThrows(
Exception.class, () -> EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), null)
);
assertThat(thrownException instanceof NullPointerException).isTrue();
assertThat(thrownException.getMessage()).isNull();
}
}

0 comments on commit 5b60fd1

Please sign in to comment.