Skip to content

Commit dc883f4

Browse files
authored
Feature: Improve transfer blacklist management (#3635)
1 parent 2eeeb06 commit dc883f4

File tree

7 files changed

+540
-22
lines changed

7 files changed

+540
-22
lines changed

.github/workflows/sonarqube.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,19 @@ jobs:
1717
- name: Create temporary global.json
1818
run: echo '{"sdk":{"version":"8.0.*"}}' > ./global.json
1919
- name: Set up JDK 17
20-
uses: actions/setup-java@v1
20+
uses: actions/setup-java@v4
2121
with:
22+
distribution: 'temurin'
2223
java-version: 17
2324
- name: Cache SonarQube packages
24-
uses: actions/cache@v1
25+
uses: actions/cache@v4
2526
with:
2627
path: ~/.sonar/cache
2728
key: ${{ runner.os }}-sonar
2829
restore-keys: ${{ runner.os }}-sonar
2930
- name: Cache SonarQube scanner
3031
id: cache-sonar-scanner
31-
uses: actions/cache@v1
32+
uses: actions/cache@v4
3233
with:
3334
path: ./.sonar/scanner
3435
key: ${{ runner.os }}-sonar-scanner

contract/AElf.Contracts.MultiToken/TokenContractState.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public partial class TokenContractState : ContractState
3838
public SingletonState<DeveloperFeeController> DeveloperFeeController { get; set; }
3939
public SingletonState<AuthorityInfo> SymbolToPayTxFeeController { get; set; }
4040
public SingletonState<AuthorityInfo> SideChainRentalController { get; set; }
41+
public SingletonState<AuthorityInfo> TransferBlackListController { get; set; }
4142

4243
/// <summary>
4344
/// symbol -> address -> is in white list.

contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,17 +853,63 @@ private void CheckTokenAlias(string alias, string collectionSymbol)
853853

854854
public override Empty AddToTransferBlackList(Address input)
855855
{
856-
AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress);
856+
AssertControllerForTransferBlackList();
857857
Assert(input != null && !input.Value.IsNullOrEmpty(), "Invalid address.");
858858
State.TransferBlackList[input] = true;
859859
return new Empty();
860860
}
861861

862+
public override Empty BatchAddToTransferBlackList(BatchAddToTransferBlackListInput input)
863+
{
864+
AssertControllerForTransferBlackList();
865+
Assert(input != null && input.Addresses != null && input.Addresses.Count > 0, "Invalid input.");
866+
867+
// Validate all addresses first
868+
foreach (var address in input.Addresses)
869+
{
870+
Assert(address != null && !address.Value.IsNullOrEmpty(), "Invalid address.");
871+
}
872+
873+
// Remove duplicates and add to blacklist
874+
var uniqueAddresses = input.Addresses.Distinct().ToList();
875+
foreach (var address in uniqueAddresses)
876+
{
877+
State.TransferBlackList[address] = true;
878+
}
879+
880+
return new Empty();
881+
}
882+
862883
public override Empty RemoveFromTransferBlackList(Address input)
863884
{
885+
// Removing from transfer blacklist requires higher security and response speed is not critical,
886+
// so it should be controlled by Parliament.
864887
AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress);
865888
Assert(input != null && !input.Value.IsNullOrEmpty(), "Invalid address.");
866889
State.TransferBlackList[input] = false;
867890
return new Empty();
868891
}
892+
893+
public override Empty BatchRemoveFromTransferBlackList(BatchRemoveFromTransferBlackListInput input)
894+
{
895+
// Removing from transfer blacklist requires higher security and response speed is not critical,
896+
// so it should be controlled by Parliament.
897+
AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress);
898+
Assert(input != null && input.Addresses != null && input.Addresses.Count > 0, "Invalid input.");
899+
900+
// Validate all addresses first
901+
foreach (var address in input.Addresses)
902+
{
903+
Assert(address != null && !address.Value.IsNullOrEmpty(), "Invalid address.");
904+
}
905+
906+
// Remove duplicates and remove from blacklist
907+
var uniqueAddresses = input.Addresses.Distinct().ToList();
908+
foreach (var address in uniqueAddresses)
909+
{
910+
State.TransferBlackList[address] = false;
911+
}
912+
913+
return new Empty();
914+
}
869915
}

contract/AElf.Contracts.MultiToken/TokenContract_Method_Authorization.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ public override Empty ChangeDeveloperController(AuthorityInfo input)
8787
return new Empty();
8888
}
8989

90+
public override Empty ChangeTransferBlackListController(AuthorityInfo input)
91+
{
92+
AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress);
93+
var organizationExist = CheckOrganizationExist(input);
94+
Assert(organizationExist, "Invalid authority input.");
95+
State.TransferBlackListController.Value = input;
96+
return new Empty();
97+
}
98+
9099
private void CreateReferendumControllerForUserFee(Address parliamentAddress)
91100
{
92101
State.ReferendumContract.CreateOrganizationBySystemContract.Send(
@@ -364,6 +373,13 @@ private AuthorityInfo GetDefaultSideChainRentalController(AuthorityInfo defaultP
364373
};
365374
}
366375

376+
private AuthorityInfo GetTransferBlackListController()
377+
{
378+
if (State.TransferBlackListController.Value == null)
379+
return GetDefaultParliamentController();
380+
return State.TransferBlackListController.Value;
381+
}
382+
367383
private void AssertDeveloperFeeController()
368384
{
369385
Assert(State.DeveloperFeeController.Value != null,
@@ -396,5 +412,11 @@ private void AssertControllerForSideChainRental()
396412
Assert(State.SideChainRentalController.Value.OwnerAddress == Context.Sender, "no permission");
397413
}
398414

415+
private void AssertControllerForTransferBlackList()
416+
{
417+
var controller = GetTransferBlackListController();
418+
Assert(Context.Sender == controller.OwnerAddress, "No permission");
419+
}
420+
399421
#endregion
400422
}

contract/AElf.Contracts.MultiToken/TokenContract_Views.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,10 @@ public override BoolValue IsInTransferBlackList(Address input)
298298
{
299299
return new BoolValue { Value = State.TransferBlackList[input] };
300300
}
301+
302+
[View]
303+
public override AuthorityInfo GetTransferBlackListController(Empty input)
304+
{
305+
return GetTransferBlackListController();
306+
}
301307
}

protobuf/token_contract_impl.proto

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ service TokenContractImpl {
7777
rpc ChangeDeveloperController (AuthorityInfo) returns (google.protobuf.Empty) {
7878
}
7979

80+
// Change the governance organization of the transfer blacklist management.
81+
rpc ChangeTransferBlackListController (AuthorityInfo) returns (google.protobuf.Empty) {
82+
}
83+
8084
rpc ConfigTransactionFeeFreeAllowances (ConfigTransactionFeeFreeAllowancesInput) returns (google.protobuf.Empty) {
8185
}
8286

@@ -136,6 +140,11 @@ service TokenContractImpl {
136140
option (aelf.is_view) = true;
137141
}
138142

143+
// Query the governance organization of the transfer blacklist management.
144+
rpc GetTransferBlackListController (google.protobuf.Empty) returns (AuthorityInfo) {
145+
option (aelf.is_view) = true;
146+
}
147+
139148
// Compute the virtual address for locking.
140149
rpc GetVirtualAddressForLocking (GetVirtualAddressForLockingInput) returns (aelf.Address) {
141150
option (aelf.is_view) = true;
@@ -186,12 +195,22 @@ service TokenContractImpl {
186195
rpc ExtendSeedExpirationTime (ExtendSeedExpirationTimeInput) returns (google.protobuf.Empty) {
187196
}
188197

189-
// Add an address to the transfer blacklist. Only parliament owner can call this method.
198+
// Add an address to the transfer blacklist.
190199
rpc AddToTransferBlackList (aelf.Address) returns (google.protobuf.Empty) {
191200
}
201+
202+
// Add multiple addresses to the transfer blacklist.
203+
rpc BatchAddToTransferBlackList (BatchAddToTransferBlackListInput) returns (google.protobuf.Empty) {
204+
}
205+
192206
// Remove an address from the transfer blacklist. Only parliament owner can call this method.
193207
rpc RemoveFromTransferBlackList (aelf.Address) returns (google.protobuf.Empty) {
194208
}
209+
210+
// Remove multiple addresses from the transfer blacklist. Only parliament owner can call this method.
211+
rpc BatchRemoveFromTransferBlackList (BatchRemoveFromTransferBlackListInput) returns (google.protobuf.Empty) {
212+
}
213+
195214
// Check if an address is in the transfer blacklist.
196215
rpc IsInTransferBlackList (aelf.Address) returns (google.protobuf.BoolValue) {
197216
option (aelf.is_view) = true;
@@ -471,4 +490,12 @@ message SeedExpirationTimeUpdated {
471490
string symbol = 2;
472491
int64 old_expiration_time = 3;
473492
int64 new_expiration_time = 4;
493+
}
494+
495+
message BatchAddToTransferBlackListInput {
496+
repeated aelf.Address addresses = 1;
497+
}
498+
499+
message BatchRemoveFromTransferBlackListInput {
500+
repeated aelf.Address addresses = 1;
474501
}

0 commit comments

Comments
 (0)