Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ public class CommonParameter {

@Getter
@Setter
public boolean allowShieldedTransactionApi; // clearParam: true
public boolean allowShieldedTransactionApi; // clearParam: false
@Getter
@Setter
public long blockNumForEnergyLimit;
Expand Down
408 changes: 207 additions & 201 deletions framework/src/main/java/org/tron/core/Wallet.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ public static void applyConfigParams(
logger.warn("Configuring [node.fullNodeAllowShieldedTransaction] will be deprecated. "
+ "Please use [node.allowShieldedTransactionApi] instead.");
} else {
PARAMETER.allowShieldedTransactionApi = true;
PARAMETER.allowShieldedTransactionApi = false;
}

PARAMETER.zenTokenId = config.hasPath(ConfigKey.NODE_ZEN_TOKENID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.tron.api.GrpcAPI;
import org.tron.api.GrpcAPI.BytesMessage;
import org.tron.api.GrpcAPI.ShieldedTRC20Parameters;
import org.tron.common.math.StrictMathWrapper;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.ByteUtil;
import org.tron.common.utils.Sha256Hash;
Expand Down Expand Up @@ -547,8 +548,8 @@ public void addSpend(
byte[] anchor,
byte[] path,
long position) throws ZksnarkException {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
spends.add(new SpendDescriptionInfo(expsk, note, anchor, path, position));
valueBalance += note.getValue();
}

public void addSpend(
Expand All @@ -558,8 +559,8 @@ public void addSpend(
byte[] anchor,
byte[] path,
long position) {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
spends.add(new SpendDescriptionInfo(expsk, note, alpha, anchor, path, position));
valueBalance += note.getValue();
}

public void addSpend(
Expand All @@ -570,23 +571,23 @@ public void addSpend(
byte[] anchor,
byte[] path,
long position) {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
spends.add(new SpendDescriptionInfo(ak, nsk, note, alpha, anchor, path, position));
valueBalance += note.getValue();
}

public void addOutput(byte[] ovk, PaymentAddress to, long value, byte[] memo)
throws ZksnarkException {
Note note = new Note(to, value);
note.setMemo(memo);
valueBalance = StrictMathWrapper.subtractExact(valueBalance, value);
receives.add(new ReceiveDescriptionInfo(ovk, note));
valueBalance -= value;
}

public void addOutput(byte[] ovk, DiversifierT d, byte[] pkD, long value, byte[] r, byte[] memo) {
Note note = new Note(d, pkD, value, r);
note.setMemo(memo);
valueBalance = StrictMathWrapper.subtractExact(valueBalance, value);
receives.add(new ReceiveDescriptionInfo(ovk, note));
valueBalance -= value;
}

public static class SpendDescriptionInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.tron.common.math.StrictMathWrapper;
import org.tron.common.utils.ByteArray;
import org.tron.common.zksnark.IncrementalMerkleVoucherContainer;
import org.tron.common.zksnark.JLibrustzcash;
Expand Down Expand Up @@ -66,17 +67,17 @@ public ZenTransactionBuilder() {
}

public void addSpend(SpendDescriptionInfo spendDescriptionInfo) {
valueBalance = StrictMathWrapper.addExact(valueBalance, spendDescriptionInfo.note.getValue());
spends.add(spendDescriptionInfo);
valueBalance += spendDescriptionInfo.note.getValue();
}

public void addSpend(
ExpandedSpendingKey expsk,
Note note,
byte[] anchor,
IncrementalMerkleVoucherContainer voucher) throws ZksnarkException {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
spends.add(new SpendDescriptionInfo(expsk, note, anchor, voucher));
valueBalance += note.getValue();
}

public void addSpend(
Expand All @@ -85,8 +86,8 @@ public void addSpend(
byte[] alpha,
byte[] anchor,
IncrementalMerkleVoucherContainer voucher) {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
spends.add(new SpendDescriptionInfo(expsk, note, alpha, anchor, voucher));
valueBalance += note.getValue();
}

public void addSpend(
Expand All @@ -97,23 +98,23 @@ public void addSpend(
byte[] alpha,
byte[] anchor,
IncrementalMerkleVoucherContainer voucher) {
valueBalance = StrictMathWrapper.addExact(valueBalance, note.getValue());
spends.add(new SpendDescriptionInfo(ak, nsk, ovk, note, alpha, anchor, voucher));
valueBalance += note.getValue();
}

public void addOutput(byte[] ovk, PaymentAddress to, long value, byte[] memo)
throws ZksnarkException {
Note note = new Note(to, value);
note.setMemo(memo);
valueBalance = StrictMathWrapper.subtractExact(valueBalance, value);
receives.add(new ReceiveDescriptionInfo(ovk, note));
valueBalance -= value;
}

public void addOutput(byte[] ovk, DiversifierT d, byte[] pkD, long value, byte[] r, byte[] memo) {
Note note = new Note(d, pkD, value, r);
note.setMemo(memo);
valueBalance = StrictMathWrapper.subtractExact(valueBalance, value);
receives.add(new ReceiveDescriptionInfo(ovk, note));
valueBalance -= value;
}

public void setTransparentInput(byte[] address, long value) {
Expand Down
8 changes: 7 additions & 1 deletion framework/src/main/resources/config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,13 @@ node {

minParticipationRate = 15

# allowShieldedTransactionApi = true
# WARNING: Some shielded transaction APIs require sending private keys as parameters.
# Calling these APIs on untrusted or remote nodes may leak your private keys.
# It is recommended to invoke them locally for development and testing.
# To opt in, set: allowShieldedTransactionApi = true
# Migration: the legacy key node.fullNodeAllowShieldedTransaction is still supported
# but deprecated; please migrate to node.allowShieldedTransactionApi.
# allowShieldedTransactionApi = false

# openPrintLog = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.bouncycastle.util.encoders.Hex;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
Expand Down Expand Up @@ -73,9 +74,18 @@ public class ShieldedTRC20BuilderTest extends BaseTest {
VerifyTransferProof transferContract = new VerifyTransferProof();
VerifyBurnProof burnContract = new VerifyBurnProof();

private static boolean origShieldedApi;

@BeforeClass
public static void initZksnarkParams() {
ZksnarkInitService.librustzcashInitZksnarkParams();
origShieldedApi = Args.getInstance().allowShieldedTransactionApi;
Args.getInstance().allowShieldedTransactionApi = true;
}

@AfterClass
public static void restoreShieldedApi() {
Args.getInstance().allowShieldedTransactionApi = origShieldedApi;
}

@Ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,9 @@ public void publicAddressToShieldNoteValueFailure() {
actuator.validate();
actuator.execute(ret);
Assert.assertTrue(false);
} catch (ArithmeticException e) {
// StrictMathWrapper.subtractExact throws ArithmeticException on overflow
Assert.assertTrue(true);
} catch (ContractValidateException e) {
Assert.assertTrue(e instanceof ContractValidateException);
Assert.assertEquals("librustzcashSaplingFinalCheck error", e.getMessage());
Expand Down Expand Up @@ -1346,5 +1349,58 @@ public void shieldAddressToPublic() {
Assert.assertTrue(false);
}
}

/**
* Test that shielded transfer transaction validation works even when
* allowShieldedTransactionApi is disabled. This verifies that the API flag
* only gates wallet/helper APIs, not the core transaction validation logic.
*/
@Test
public void shieldedTransferValidationWorksWhenApiDisabled() {
boolean orig = Args.getInstance().isAllowShieldedTransactionApi();
// Disable the shielded API (this should NOT affect transaction validation)
Args.getInstance().setAllowShieldedTransactionApi(false);

dbManager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1);
dbManager.getDynamicPropertiesStore().saveTotalShieldedPoolValue(AMOUNT);

try {
ZenTransactionBuilder builder = new ZenTransactionBuilder(wallet);
SpendingKey sk = SpendingKey.random();
ExpandedSpendingKey expsk = sk.expandedSpendingKey();
PaymentAddress address = sk.defaultAddress();
Note note = new Note(address, AMOUNT);
IncrementalMerkleVoucherContainer voucher = createSimpleMerkleVoucherContainer(note.cm());
byte[] anchor = voucher.root().getContent().toByteArray();
dbManager.getMerkleContainer()
.putMerkleTreeIntoStore(anchor, voucher.getVoucherCapsule().getTree());
builder.addSpend(expsk, note, anchor, voucher);

addZeroValueOutputNote(builder);

long fee = dbManager.getDynamicPropertiesStore().getShieldedTransactionCreateAccountFee();
String addressNotExist =
Wallet.getAddressPreFixString() + "8ba2aaae540c642e44e3bed5522c63bbc21f0000";

builder.setTransparentOutput(ByteArray.fromHexString(addressNotExist), AMOUNT - fee);

TransactionCapsule transactionCap = builder.build();
Contract contract =
transactionCap.getInstance().toBuilder().getRawDataBuilder().getContract(0);
ShieldedTransferActuator actuator = new ShieldedTransferActuator();
actuator.setChainBaseManager(dbManager.getChainBaseManager()).setContract(contract)
.setTx(transactionCap);

// Validation should succeed even when API is disabled
actuator.validate();
} catch (ContractValidateException e) {
Assert.fail("Shielded transfer validation should not throw ContractValidateException: "
+ e.getMessage());
} catch (Exception e) {
Assert.fail("Shielded transfer should not throw Exception: " + e.getMessage());
} finally {
Args.getInstance().setAllowShieldedTransactionApi(orig);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -360,5 +360,14 @@ public void testConfigStorageDefaults() {

Args.clearParam();
}

@Test
public void testAllowShieldedTransactionApiDefault() {
Args.setParam(new String[]{}, TestConstants.TEST_CONF);
Assert.assertFalse(Args.getInstance().isAllowShieldedTransactionApi());
Args.getInstance().setAllowShieldedTransactionApi(true);
Assert.assertTrue(Args.getInstance().isAllowShieldedTransactionApi());
Args.getInstance().setAllowShieldedTransactionApi(false);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public class RpcApiServicesTest {
public static void init() throws IOException {
Args.setParam(new String[] {"-d", temporaryFolder.newFolder().toString()},
TestConstants.TEST_CONF);
getInstance().allowShieldedTransactionApi = true;
Assert.assertEquals(5, getInstance().getRpcMaxRstStream());
Assert.assertEquals(10, getInstance().getRpcSecondsPerWindow());
String OWNER_ADDRESS = Wallet.getAddressPreFixString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import java.io.UnsupportedEncodingException;
import javax.annotation.Resource;
import org.apache.http.client.methods.HttpPost;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
Expand All @@ -18,6 +20,8 @@

public class CreateSpendAuthSigServletTest extends BaseTest {

private static boolean origShieldedApi;

static {
Args.setParam(
new String[]{
Expand All @@ -26,6 +30,17 @@ public class CreateSpendAuthSigServletTest extends BaseTest {
);
}

@BeforeClass
public static void enableShieldedApi() {
origShieldedApi = Args.getInstance().allowShieldedTransactionApi;
Args.getInstance().allowShieldedTransactionApi = true;
}

@AfterClass
public static void restoreShieldedApi() {
Args.getInstance().allowShieldedTransactionApi = origShieldedApi;
}

@Resource
private CreateSpendAuthSigServlet createSpendAuthSigServlet;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import javax.annotation.Resource;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.tron.common.BaseTest;
import org.tron.common.TestConstants;
Expand Down Expand Up @@ -38,10 +40,23 @@ public class MerkleContainerTest extends BaseTest {
// private static MerkleContainer merkleContainer;


private static boolean origShieldedApi;

static {
Args.setParam(new String[]{"-d", dbPath()}, TestConstants.TEST_CONF);
}

@BeforeClass
public static void enableShieldedApi() {
origShieldedApi = Args.getInstance().allowShieldedTransactionApi;
Args.getInstance().allowShieldedTransactionApi = true;
}

@AfterClass
public static void restoreShieldedApi() {
Args.getInstance().allowShieldedTransactionApi = origShieldedApi;
}

/*@Before
public void init() {
merkleContainer = MerkleContainer
Expand Down
Binary file removed sprout-verifying.key
Binary file not shown.
Loading