XRPL 결제 및 오퍼 교차에서 프런트 러닝 또는 트랜잭션 샌드위치 공격 가능성에 대한 우려가 제기되었습니다.
제가 설명한 이유들 때문에 이 문제에 크게 우려하지는 않지만, 이 공격을 근절할 수 있는 비교적 간단한 방안을 제안하고자 합니다. 이는 트랜잭션 예약 스키마로, 공개된 이후에 생성된 어떤 트랜잭션보다 먼저 실행되도록 보장합니다.
이것이 해당 스키마이며, 프런트 러닝이나 샌드위치 공격에 대한 우려를 없애줍니다.
트랜잭션 슬롯 예약
새로운 ledger 객체인 ReservedTxns를 제안합니다. 이 객체는 ledger 시퀀스 번호와 트랜잭션 ID 배열을 포함합니다. 고정 문자열과 ledger 시퀀스 번호의 해시로 생성된 인덱스에 저장됩니다.
새로운 트랜잭션인 TxnReserve를 제안하여 트랜잭션 실행 슬롯을 예약합니다. 파라미터로 ledger 번호와 트랜잭션 ID를 받습니다.
다음 조건을 만족하면 성공합니다:
1) 일반 트랜잭션 수수료의 최소 두 배에 해당하는 수수료를 지불합니다.
2) 모든 일반 트랜잭션 실행 요구사항을 충족합니다.
3) 트랜잭션에 지정된 ledger 시퀀스 번호가 현재 ledger 시퀀스 번호보다 크고, 현재 ledger 시퀀스 번호보다 16개 이하의 ledger만큼 앞서지 않아야 합니다. 이 검증에 실패하면 트랜잭션이 TEC 됩니다.
4) 지정된 ledger 시퀀스 번호에 대한 ReservedTxns 객체가 없거나, 존재한다면 32개 미만의 트랜잭션 ID를 포함하고 지정된 트랜잭션 ID를 포함하지 않아야 합니다. 이 중 하나라도 실패하면 트랜잭션이 TEC 됩니다.
성공하면 지정된 ledger 인덱스에 ReservedTxns 객체가 없을 경우 생성하고, 해당 트랜잭션 ID를 객체의 트랜잭션 ID 배열 끝에 추가합니다.
예약된 트랜잭션 방송
트랜잭션이 ledger X에 예약 슬롯을 가지고 있다면, ledger X‑1의 초기 제안이 모두 수신되었거나 최종 합의 트랜잭션 세트가 알려졌을 때 즉시 방송해야 합니다. XRPL 소프트웨어는 해당 시점을 공개하는 기능을 제공하도록 수정되어야 하며, 필요시 해당 시점에만 방송할 트랜잭션 목록을 보관할 수 있어야 합니다.
XRPL 소프트웨어는 최근에 방송되지 않은 예약 슬롯을 가진 트랜잭션은 항상 방송해야 합니다. 서버가 해당 트랜잭션이 성공하지 않을 것으로 판단하더라도 적용됩니다. 예약 트랜잭션 수수료가 두 배가 되었으므로 중계 비용은 이미 선불이며, 이는 공격이 아닙니다.
예약 트랜잭션으로 실행될 의도라면 마지막 유효 ledger를 예상 실행 ledger로 설정해야 합니다. 이렇게 하면 지연되더라도 샌드위치나 프런트 러닝을 방지할 수 있습니다.
실행 메커니즘
각 ledger가 실행될 때, 트랜잭션 세트의 어떤 트랜잭션을 실행하기 전에 다음 단계가 추가됩니다:
1) 해당 ledger 시퀀스 번호에 대한 예약 트랜잭션을 포함하는 ledger 객체를 가져옵니다. 없으면 나머지 단계를 건너뛰고 트랜잭션을 정상적으로 실행합니다.
2) 예약 트랜잭션 집합의 각 트랜잭션 ID에 대해, 그 트랜잭션이 합의 집합에 있으면 실행하고, 다시 실행되지 않도록 합의 집합에서 제거합니다.
3) 해당 ledger 시퀀스 번호에 대한 예약 트랜잭션 객체를 ledger에서 제거합니다.
DoS 공격 저항
이 스키마에 대한 이론적 공격이 존재합니다. 공격자는 다수의 ledger에 대해 모든 예약 슬롯을 채워 다른 사용자가 이 스키마를 사용해 트랜잭션을 보호하지 못하도록 서비스 거부를 유발할 수 있습니다. 이는 지속적인 비용 지불이 필요하고 다른 사용자는 공격이 끝날 때까지 기다릴 수 있기 때문에 완화됩니다. 그러나 비용이 충분히 낮아 이론적으로 무한히 진행할 수 있습니다.
간단한 해결책은 객체가 가득 차기 시작할 때 예약 트랜잭션 수수료를 단계적으로 올리는 것입니다. 예를 들어, 16개의 예약 슬롯에 도달하면 기본 예약금까지 선형적으로 수수료를 인상할 수 있습니다. 30개에 도달하면 수수료를 기본 예약금의 세 배까지 올릴 수 있습니다.
필요하다면 한도가 64까지 증가시킬 수 있습니다. 사용자가 비용을 계속 지불하려는 경우에만 적용됩니다. 이러한 비용이 실제로 지불되는 일은 거의 없을 것이며, 공격을 실질적으로 비현실화시킵니다. 공격자는 5초마다 트랜잭션을 보호하기 위해 누군가가 지불하려는 금액의 여러 배를 지불해야 합니다.