NonceProvider

NonceProvider는 nonce를 저장하고 새로 사용할 값을 제공해주는 interface입니다. Heraj는 thread-safe하고 memmory leak을 방지하는 기능을 가지고 있는 SimpleNonceProvider를 제공합니다. SimpleNonceProvider는 용량이 가득찼을 때 새로운 값이 들어오는 경우 가장 오래 전에 사용된 주소에 해당하는 값을 삭제합니다.

Create

SimpleNonceProvider를 생성합니다.

저장 용량을 지정해서 생성합니다.

// create nonce provider with capacity 100
NonceProvider nonceProvider = new SimpleNonceProvider(100);

저장 용량을 지정하지 않고 생성합니다.

// create nonce provider with capacity 1000
NonceProvider nonceProvider = new SimpleNonceProvider();

Bind

계정의 주소에 해당하는 nonce를 설정합니다. 용량이 가득찬 경우 가장 오래 전에 사용된 주소에 해당하는 정보가 삭제됩니다.

주소를 가지고 설정합니다.

AccountAddress accountAddress = AccountAddress
    .of("AmNrsAqkXhQfE6sGxTutQkf9ekaYowaJFLekEm8qvDr1RB1AnsiM");
NonceProvider nonceProvider = new SimpleNonceProvider();
nonceProvider.bindNonce(accountAddress, 30L);
System.out.println("Binded nonce: " + nonceProvider.getLastUsedNonce(accountAddress));

계정 상태를 가지고 설정합니다. 계정의 상태에 들어있는 주소로 설정됩니다.

AccountAddress accountAddress = AccountAddress
    .of("AmNrsAqkXhQfE6sGxTutQkf9ekaYowaJFLekEm8qvDr1RB1AnsiM");
AccountState accountState = client.getAccountOperation().getState(accountAddress);
NonceProvider nonceProvider = new SimpleNonceProvider();
System.out.println("Binded nonce: " + nonceProvider.getLastUsedNonce(accountAddress));

Use

nonce를 증가시키고 새롭게 사용할 값을 리턴합니다. 이 연산은 thread-safe합니다.

AergoKey signer = richKey;
NonceProvider nonceProvider = new SimpleNonceProvider();
long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
System.out.println("Next nonce: " + nonce);

가장 최근에 사용된 nonce값을 리턴합니다.

AergoKey signer = richKey;
NonceProvider nonceProvider = new SimpleNonceProvider();
long nonce = nonceProvider.getLastUsedNonce(signer.getAddress());
System.out.println("Last used nonce: " + nonce);

Example

// prepare signer
AergoKey signer = richKey;

// create an nonce provider
AccountState accountState = client.getAccountOperation().getState(signer.getAddress());
NonceProvider nonceProvider = new SimpleNonceProvider();
nonceProvider.bindNonce(accountState);

// print current
long currentNonce = nonceProvider.getLastUsedNonce(signer.getAddress());
System.out.println("Current nonce: " + currentNonce);

// request using thread pool
AccountAddress accountAddress = AccountAddress
    .of("AmNrsAqkXhQfE6sGxTutQkf9ekaYowaJFLekEm8qvDr1RB1AnsiM");
ExecutorService service = Executors.newCachedThreadPool();
IntStream.range(0, 1000).forEach(i -> {
  service.submit(() -> {
    // get nonce to use
    long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
    client.getTransactionOperation().sendTx(signer, accountAddress, Aer.ONE, nonce,
        Fee.INFINITY, BytesValue.EMPTY);
  });
});

// stop the service
service.awaitTermination(3000L, TimeUnit.MILLISECONDS);
service.shutdown();

// should print 1000
long lastUsedNonce = nonceProvider.getLastUsedNonce(signer.getAddress());
System.out.println("Nonce difference: " + (lastUsedNonce - currentNonce));