mirror of
https://github.com/MAGICGrants/flutter_libsparkmobile.git
synced 2026-01-08 04:33:50 -05:00
more frees and remove unused functions
This commit is contained in:
@@ -407,12 +407,38 @@ abstract final class LibSpark {
|
||||
txHashPtr,
|
||||
);
|
||||
|
||||
// todo: more comprehensive frees
|
||||
malloc.free(privateKeyPtr);
|
||||
malloc.free(recipientsPtr);
|
||||
|
||||
for (int i = 0; i < privateRecipients.length; i++) {
|
||||
malloc.free(privateRecipientsPtr[i].output.ref.memo);
|
||||
malloc.free(privateRecipientsPtr[i].output.ref.address);
|
||||
malloc.free(privateRecipientsPtr[i].output);
|
||||
}
|
||||
malloc.free(privateRecipientsPtr);
|
||||
|
||||
for (int i = 0; i < serializedCoins.length; i++) {
|
||||
malloc.free(serializedCoinsPtr[i].serializedCoinContext.ref.data);
|
||||
malloc.free(serializedCoinsPtr[i].serializedCoinContext);
|
||||
malloc.free(serializedCoinsPtr[i].serializedCoin.ref.data);
|
||||
malloc.free(serializedCoinsPtr[i].serializedCoin);
|
||||
}
|
||||
malloc.free(serializedCoinsPtr);
|
||||
|
||||
for (int i = 0; i < allAnonymitySets.length; i++) {
|
||||
for (int j = 0; j < allAnonymitySets[i].set.length; j++) {
|
||||
malloc.free(coverSetDataAllPtr[i].cover_set[j].data);
|
||||
}
|
||||
malloc.free(coverSetDataAllPtr[i].cover_set);
|
||||
malloc.free(coverSetDataAllPtr[i].cover_set_representation);
|
||||
}
|
||||
malloc.free(coverSetDataAllPtr);
|
||||
|
||||
for (int i = 0; i < idAndBlockHashes.length; i++) {
|
||||
malloc.free(idAndBlockHashesPtr[i].hash);
|
||||
}
|
||||
malloc.free(idAndBlockHashesPtr);
|
||||
|
||||
malloc.free(txHashPtr);
|
||||
|
||||
if (result.address == nullptr.address) {
|
||||
@@ -449,241 +475,6 @@ abstract final class LibSpark {
|
||||
);
|
||||
}
|
||||
|
||||
static ({int changeToMint, List<LibSparkCoin> coins}) getCoinsToSpend({
|
||||
required int sendAmount,
|
||||
required int recipientsToSubtractFee,
|
||||
required List<LibSparkCoin> coins,
|
||||
required int privateRecipientsCount,
|
||||
required int recipientsCount,
|
||||
}) {
|
||||
final coinsPtr = malloc.allocate<CCSparkMintMeta>(
|
||||
sizeOf<CCSparkMintMeta>() * coins.length,
|
||||
);
|
||||
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
coinsPtr[i].height = coins[i].height!;
|
||||
coinsPtr[i].id = coins[i].id!;
|
||||
coinsPtr[i].isUsed = coins[i].isUsed! ? 1 : 0;
|
||||
coinsPtr[i].txid = coins[i].txHash!.unsignedCharPointer();
|
||||
coinsPtr[i].i = coins[i].diversifier!.toInt();
|
||||
coinsPtr[i].d = coins[i].encryptedDiversifier!.unsignedCharPointer();
|
||||
coinsPtr[i].dLength = coins[i].encryptedDiversifier!.length;
|
||||
coinsPtr[i].nonceHex = coins[i].nonceHex!.toNativeUtf8().cast<Char>();
|
||||
coinsPtr[i].nonceHexLength = coins[i].nonceHex!.length;
|
||||
coinsPtr[i].memo = coins[i].memo!.toNativeUtf8().cast<Char>();
|
||||
coinsPtr[i].memoLength = coins[i].memo!.length;
|
||||
coinsPtr[i].serial_context =
|
||||
coins[i].serialContext!.unsignedCharPointer();
|
||||
coinsPtr[i].serial_contextLength = coins[i].serialContext!.length;
|
||||
coinsPtr[i].type = coins[i].type.value;
|
||||
|
||||
final serCoin = base64Decode(coins[i].serializedCoin!);
|
||||
coinsPtr[i].serializedCoin = serCoin.unsignedCharPointer();
|
||||
coinsPtr[i].serializedCoinLength = serCoin.length;
|
||||
}
|
||||
|
||||
final result = _bindings.getCoinsToSpend(
|
||||
sendAmount,
|
||||
coinsPtr,
|
||||
coins.length,
|
||||
);
|
||||
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
malloc.free(coinsPtr[i].txid);
|
||||
malloc.free(coinsPtr[i].d);
|
||||
malloc.free(coinsPtr[i].nonceHex);
|
||||
malloc.free(coinsPtr[i].memo);
|
||||
malloc.free(coinsPtr[i].serial_context);
|
||||
malloc.free(coinsPtr[i].serializedCoin);
|
||||
}
|
||||
malloc.free(coinsPtr);
|
||||
|
||||
if (result.ref.errorMessageLength > 0) {
|
||||
final ex = Exception(
|
||||
result.ref.errorMessage.cast<Utf8>().toDartString(
|
||||
length: result.ref.errorMessageLength,
|
||||
),
|
||||
);
|
||||
malloc.free(result.ref.errorMessage);
|
||||
malloc.free(result);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
final ({int changeToMint, List<LibSparkCoin> coins}) ret = (
|
||||
changeToMint: result.ref.changeToMint,
|
||||
coins: <LibSparkCoin>[],
|
||||
);
|
||||
|
||||
for (int i = 0; i < result.ref.length; i++) {
|
||||
final LibSparkCoinType coinType;
|
||||
switch (result.ref.list[i].type) {
|
||||
case 0:
|
||||
coinType = LibSparkCoinType.mint;
|
||||
break;
|
||||
case 1:
|
||||
coinType = LibSparkCoinType.mint;
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Unknown coin type \"${result.ref.list[i].type}\" found.",
|
||||
);
|
||||
}
|
||||
|
||||
final coin = LibSparkCoin(
|
||||
type: coinType,
|
||||
id: result.ref.list[i].id,
|
||||
height: result.ref.list[i].height,
|
||||
isUsed: result.ref.list[i].isUsed > 0,
|
||||
nonceHex: result.ref.list[i].nonceHex
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: result.ref.list[i].nonceHexLength),
|
||||
value: BigInt.from(result.ref.list[i].v),
|
||||
memo: result.ref.list[i].memo
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: result.ref.list[i].memoLength),
|
||||
txHash: result.ref.list[i].txid.toUint8List(32),
|
||||
serialContext: result.ref.list[i].serial_context
|
||||
.toUint8List(result.ref.list[i].serial_contextLength),
|
||||
diversifier: BigInt.from(result.ref.list[i].i),
|
||||
encryptedDiversifier:
|
||||
result.ref.list[i].d.toUint8List(result.ref.list[i].dLength),
|
||||
serializedCoin: base64Encode(result.ref.list[i].serializedCoin
|
||||
.toUint8List(result.ref.list[i].serializedCoinLength)),
|
||||
);
|
||||
|
||||
ret.coins.add(coin);
|
||||
|
||||
malloc.free(result.ref.list[i].txid);
|
||||
malloc.free(result.ref.list[i].d);
|
||||
malloc.free(result.ref.list[i].nonceHex);
|
||||
malloc.free(result.ref.list[i].memo);
|
||||
malloc.free(result.ref.list[i].serial_context);
|
||||
malloc.free(result.ref.list[i].serializedCoin);
|
||||
}
|
||||
|
||||
malloc.free(result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ({int fee, List<LibSparkCoin> coins}) selectSparkCoins({
|
||||
required int requiredAmount,
|
||||
required bool subtractFeeFromAmount,
|
||||
required List<LibSparkCoin> coins,
|
||||
required int privateRecipientsCount,
|
||||
}) {
|
||||
final coinsPtr = malloc.allocate<CCSparkMintMeta>(
|
||||
sizeOf<CCSparkMintMeta>() * coins.length,
|
||||
);
|
||||
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
coinsPtr[i].height = coins[i].height!;
|
||||
coinsPtr[i].id = coins[i].id!;
|
||||
coinsPtr[i].isUsed = coins[i].isUsed! ? 1 : 0;
|
||||
coinsPtr[i].txid = coins[i].txHash!.unsignedCharPointer();
|
||||
coinsPtr[i].i = coins[i].diversifier!.toInt();
|
||||
coinsPtr[i].d = coins[i].encryptedDiversifier!.unsignedCharPointer();
|
||||
coinsPtr[i].dLength = coins[i].encryptedDiversifier!.length;
|
||||
coinsPtr[i].nonceHex = coins[i].nonceHex!.toNativeUtf8().cast<Char>();
|
||||
coinsPtr[i].nonceHexLength = coins[i].nonceHex!.length;
|
||||
coinsPtr[i].memo = coins[i].memo!.toNativeUtf8().cast<Char>();
|
||||
coinsPtr[i].memoLength = coins[i].memo!.length;
|
||||
coinsPtr[i].serial_context =
|
||||
coins[i].serialContext!.unsignedCharPointer();
|
||||
coinsPtr[i].serial_contextLength = coins[i].serialContext!.length;
|
||||
coinsPtr[i].type = coins[i].type.value;
|
||||
|
||||
final serCoin = base64Decode(coins[i].serializedCoin!);
|
||||
coinsPtr[i].serializedCoin = serCoin.unsignedCharPointer();
|
||||
coinsPtr[i].serializedCoinLength = serCoin.length;
|
||||
}
|
||||
|
||||
final result = _bindings.selectSparkCoins(
|
||||
requiredAmount,
|
||||
subtractFeeFromAmount ? 1 : 0,
|
||||
coinsPtr,
|
||||
coins.length,
|
||||
privateRecipientsCount,
|
||||
);
|
||||
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
malloc.free(coinsPtr[i].txid);
|
||||
malloc.free(coinsPtr[i].d);
|
||||
malloc.free(coinsPtr[i].nonceHex);
|
||||
malloc.free(coinsPtr[i].memo);
|
||||
malloc.free(coinsPtr[i].serial_context);
|
||||
malloc.free(coinsPtr[i].serializedCoin);
|
||||
}
|
||||
malloc.free(coinsPtr);
|
||||
|
||||
if (result.ref.errorMessageLength > 0) {
|
||||
final ex = Exception(
|
||||
result.ref.errorMessage.cast<Utf8>().toDartString(
|
||||
length: result.ref.errorMessageLength,
|
||||
),
|
||||
);
|
||||
malloc.free(result.ref.errorMessage);
|
||||
malloc.free(result);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
final ({int fee, List<LibSparkCoin> coins}) ret = (
|
||||
fee: result.ref.fee,
|
||||
coins: <LibSparkCoin>[],
|
||||
);
|
||||
|
||||
for (int i = 0; i < result.ref.length; i++) {
|
||||
final LibSparkCoinType coinType;
|
||||
switch (result.ref.list[i].type) {
|
||||
case 0:
|
||||
coinType = LibSparkCoinType.mint;
|
||||
break;
|
||||
case 1:
|
||||
coinType = LibSparkCoinType.mint;
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Unknown coin type \"${result.ref.list[i].type}\" found.",
|
||||
);
|
||||
}
|
||||
|
||||
final coin = LibSparkCoin(
|
||||
type: coinType,
|
||||
id: result.ref.list[i].id,
|
||||
height: result.ref.list[i].height,
|
||||
isUsed: result.ref.list[i].isUsed > 0,
|
||||
nonceHex: result.ref.list[i].nonceHex
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: result.ref.list[i].nonceHexLength),
|
||||
value: BigInt.from(result.ref.list[i].v),
|
||||
memo: result.ref.list[i].memo
|
||||
.cast<Utf8>()
|
||||
.toDartString(length: result.ref.list[i].memoLength),
|
||||
txHash: result.ref.list[i].txid.toUint8List(32),
|
||||
serialContext: result.ref.list[i].serial_context
|
||||
.toUint8List(result.ref.list[i].serial_contextLength),
|
||||
diversifier: BigInt.from(result.ref.list[i].i),
|
||||
encryptedDiversifier:
|
||||
result.ref.list[i].d.toUint8List(result.ref.list[i].dLength),
|
||||
serializedCoin: base64Encode(result.ref.list[i].serializedCoin
|
||||
.toUint8List(result.ref.list[i].serializedCoinLength)),
|
||||
);
|
||||
|
||||
ret.coins.add(coin);
|
||||
|
||||
malloc.free(result.ref.list[i].txid);
|
||||
malloc.free(result.ref.list[i].d);
|
||||
malloc.free(result.ref.list[i].nonceHex);
|
||||
malloc.free(result.ref.list[i].memo);
|
||||
malloc.free(result.ref.list[i].serial_context);
|
||||
malloc.free(result.ref.list[i].serializedCoin);
|
||||
}
|
||||
|
||||
malloc.free(result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool validateAddress({
|
||||
required String address,
|
||||
required bool isTestNet,
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'dart:ffi' as ffi;
|
||||
///
|
||||
/// Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
|
||||
///
|
||||
class FlutterLibsparkmobileBindings {
|
||||
final class FlutterLibsparkmobileBindings {
|
||||
/// Holds the symbol lookup function.
|
||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
_lookup;
|
||||
@@ -194,54 +194,6 @@ class FlutterLibsparkmobileBindings {
|
||||
int,
|
||||
ffi.Pointer<ffi.UnsignedChar>)>();
|
||||
|
||||
ffi.Pointer<GetSparkCoinsResult> getCoinsToSpend(
|
||||
int spendAmount,
|
||||
ffi.Pointer<CCSparkMintMeta> coins,
|
||||
int coinLength,
|
||||
) {
|
||||
return _getCoinsToSpend(
|
||||
spendAmount,
|
||||
coins,
|
||||
coinLength,
|
||||
);
|
||||
}
|
||||
|
||||
late final _getCoinsToSpendPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Pointer<GetSparkCoinsResult> Function(ffi.Int64,
|
||||
ffi.Pointer<CCSparkMintMeta>, ffi.Int)>>('getCoinsToSpend');
|
||||
late final _getCoinsToSpend = _getCoinsToSpendPtr.asFunction<
|
||||
ffi.Pointer<GetSparkCoinsResult> Function(
|
||||
int, ffi.Pointer<CCSparkMintMeta>, int)>();
|
||||
|
||||
ffi.Pointer<SelectSparkCoinsResult> selectSparkCoins(
|
||||
int required1,
|
||||
int subtractFeeFromAmount,
|
||||
ffi.Pointer<CCSparkMintMeta> coins,
|
||||
int coinsLength,
|
||||
int mintNum,
|
||||
) {
|
||||
return _selectSparkCoins(
|
||||
required1,
|
||||
subtractFeeFromAmount,
|
||||
coins,
|
||||
coinsLength,
|
||||
mintNum,
|
||||
);
|
||||
}
|
||||
|
||||
late final _selectSparkCoinsPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Pointer<SelectSparkCoinsResult> Function(
|
||||
ffi.Int64,
|
||||
ffi.Int,
|
||||
ffi.Pointer<CCSparkMintMeta>,
|
||||
ffi.Int,
|
||||
ffi.Int)>>('selectSparkCoins');
|
||||
late final _selectSparkCoins = _selectSparkCoinsPtr.asFunction<
|
||||
ffi.Pointer<SelectSparkCoinsResult> Function(
|
||||
int, int, ffi.Pointer<CCSparkMintMeta>, int, int)>();
|
||||
|
||||
ffi.Pointer<SerializedMintContextResult> serializeMintContext(
|
||||
ffi.Pointer<DartInputData> inputs,
|
||||
int inputsLength,
|
||||
@@ -547,36 +499,6 @@ final class CCSparkMintMeta extends ffi.Struct {
|
||||
external int serializedCoinLength;
|
||||
}
|
||||
|
||||
final class GetSparkCoinsResult extends ffi.Struct {
|
||||
external ffi.Pointer<CCSparkMintMeta> list;
|
||||
|
||||
@ffi.Int()
|
||||
external int length;
|
||||
|
||||
@ffi.Int64()
|
||||
external int changeToMint;
|
||||
|
||||
external ffi.Pointer<ffi.Char> errorMessage;
|
||||
|
||||
@ffi.Int()
|
||||
external int errorMessageLength;
|
||||
}
|
||||
|
||||
final class SelectSparkCoinsResult extends ffi.Struct {
|
||||
external ffi.Pointer<CCSparkMintMeta> list;
|
||||
|
||||
@ffi.Int()
|
||||
external int length;
|
||||
|
||||
@ffi.Int64()
|
||||
external int fee;
|
||||
|
||||
external ffi.Pointer<ffi.Char> errorMessage;
|
||||
|
||||
@ffi.Int()
|
||||
external int errorMessageLength;
|
||||
}
|
||||
|
||||
/// FFI-friendly wrapper for a spark::CoverSetData.
|
||||
///
|
||||
/// CoverSetData: https://github.com/firoorg/sparkmobile/blob/8bf17cd3deba6c3b0d10e89282e02936d7e71cdd/src/spend_transaction.h#L28
|
||||
|
||||
@@ -305,184 +305,6 @@ SparkSpendTransactionResult* cCreateSparkSpendTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
GetSparkCoinsResult* getCoinsToSpend(int64_t spendAmount, CCSparkMintMeta* coins, int coinsLength) {
|
||||
try {
|
||||
std::vector<CSparkMintMeta> coinsToSpend_out;
|
||||
int64_t change;
|
||||
|
||||
std::list<CSparkMintMeta> _coins;
|
||||
|
||||
for (int i = 0; i < coinsLength; i++) {
|
||||
CSparkMintMeta meta;
|
||||
meta.nHeight = coins[i].height;
|
||||
meta.nId = coins[i].id;
|
||||
meta.isUsed = coins[i].isUsed > 0;
|
||||
meta.txid = uint256S((const char*)coins[i].txid);
|
||||
meta.i = coins[i].i;
|
||||
meta.d = std::vector<unsigned char>(coins[i].d, coins[i].d + coins[i].dLength);
|
||||
meta.v = coins[i].v;
|
||||
Scalar k;
|
||||
k.SetHex(std::string(coins[i].nonceHex, coins[i].nonceHexLength));
|
||||
meta.k = k;
|
||||
meta.memo = std::string(coins[i].memo, coins[i].memoLength);
|
||||
meta.serial_context = std::vector<unsigned char>(coins[i].serial_context, coins[i].serial_context + coins[i].serial_contextLength);
|
||||
meta.type = coins[i].type;
|
||||
meta.coin = deserializeCoin(coins[i].serializedCoin, coins[i].serializedCoinLength);
|
||||
|
||||
_coins.push_back(meta);
|
||||
}
|
||||
|
||||
CAmount _amount = spendAmount;
|
||||
GetCoinsToSpend(_amount, coinsToSpend_out, _coins, change);
|
||||
|
||||
GetSparkCoinsResult* result = (GetSparkCoinsResult*)malloc(sizeof(GetSparkCoinsResult));
|
||||
result->changeToMint = change;
|
||||
result->length = coinsToSpend_out.size();
|
||||
result->list = (CCSparkMintMeta*)malloc(sizeof(CCSparkMintMeta) * result->length);
|
||||
|
||||
for (int i = 0; i < coinsToSpend_out.size(); i++) {
|
||||
result->list[i].height = coinsToSpend_out[i].nHeight;
|
||||
|
||||
result->list[i].id = coinsToSpend_out[i].nId;
|
||||
|
||||
result->list[i].isUsed = coinsToSpend_out[i].isUsed;
|
||||
|
||||
result->list[i].txid = (unsigned char*)malloc(sizeof(unsigned char*) * coinsToSpend_out[i].txid.size());
|
||||
memcpy(result->list[i].txid, coinsToSpend_out[i].txid.begin(), sizeof(unsigned char) * coinsToSpend_out[i].txid.size());
|
||||
|
||||
result->list[i].i = coinsToSpend_out[i].i;
|
||||
|
||||
result->list[i].dLength = coinsToSpend_out[i].d.size();
|
||||
result->list[i].d = (unsigned char*)malloc(sizeof(unsigned char) * coinsToSpend_out[i].d.size());
|
||||
memcpy(result->list[i].d, coinsToSpend_out[i].d.data(), sizeof(unsigned char) * coinsToSpend_out[i].d.size());
|
||||
|
||||
result->list[i].v = coinsToSpend_out[i].v;
|
||||
|
||||
result->list[i].nonceHexLength = coinsToSpend_out[i].k.GetHex().length();
|
||||
result->list[i].nonceHex = (char*)malloc(sizeof(char) * result->list[i].nonceHexLength);
|
||||
memcpy(result->list[i].nonceHex, coinsToSpend_out[i].k.GetHex().c_str(), sizeof(char) * result->list[i].nonceHexLength);
|
||||
|
||||
result->list[i].memoLength = coinsToSpend_out[i].memo.length();
|
||||
result->list[i].memo = (char*)malloc(sizeof(char) * result->list[i].memoLength);
|
||||
memcpy(result->list[i].memo, coinsToSpend_out[i].memo.c_str(), sizeof(char) * result->list[i].memoLength);
|
||||
|
||||
|
||||
result->list[i].serial_context = (unsigned char*)malloc(sizeof(unsigned char) * coinsToSpend_out[i].serial_context.size());
|
||||
memcpy(result->list[i].serial_context, coinsToSpend_out[i].serial_context.data(), sizeof(unsigned char) * coinsToSpend_out[i].serial_context.size());
|
||||
result->list[i].serial_contextLength = coinsToSpend_out[i].serial_context.size();
|
||||
|
||||
CDataStream coinStream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
coinStream << coinsToSpend_out[i].coin;
|
||||
result->list[i].serializedCoinLength = coinStream.size();
|
||||
result->list[i].serializedCoin = (unsigned char*)malloc(sizeof(unsigned char) * coinStream.size());
|
||||
memcpy(result->list[i].serializedCoin, coinStream.data(), coinStream.size());
|
||||
|
||||
result->list[i].type = coinsToSpend_out[i].type;
|
||||
}
|
||||
result->errorMessageLength = 0; // false/no error
|
||||
return result;
|
||||
} catch (const std::exception& e) {
|
||||
GetSparkCoinsResult *result = (GetSparkCoinsResult*)malloc(sizeof(GetSparkCoinsResult));
|
||||
result->errorMessageLength = strlen(e.what());
|
||||
result->errorMessage = (char*)malloc(sizeof(char) * result->errorMessageLength);
|
||||
memcpy(result->errorMessage, e.what(), result->errorMessageLength);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
SelectSparkCoinsResult* selectSparkCoins(
|
||||
int64_t required,
|
||||
int subtractFeeFromAmount,
|
||||
CCSparkMintMeta* coins,
|
||||
int coinsLength,
|
||||
int mintNum
|
||||
) {
|
||||
try {
|
||||
std::list<CSparkMintMeta> _coins;
|
||||
for (int i = 0; i < coinsLength; i++) {
|
||||
for (int i = 0; i < coinsLength; i++) {
|
||||
CSparkMintMeta meta;
|
||||
meta.nHeight = coins[i].height;
|
||||
meta.nId = coins[i].id;
|
||||
meta.isUsed = coins[i].isUsed > 0;
|
||||
meta.txid = uint256S((const char*)coins[i].txid);
|
||||
meta.i = coins[i].i;
|
||||
meta.d = std::vector<unsigned char>(coins[i].d, coins[i].d + coins[i].dLength);
|
||||
meta.v = coins[i].v;
|
||||
Scalar k;
|
||||
k.SetHex(std::string(coins[i].nonceHex, coins[i].nonceHexLength));
|
||||
meta.k = k;
|
||||
meta.memo = std::string(coins[i].memo, coins[i].memoLength);
|
||||
meta.serial_context = std::vector<unsigned char>(coins[i].serial_context, coins[i].serial_context + coins[i].serial_contextLength);
|
||||
meta.type = coins[i].type;
|
||||
meta.coin = deserializeCoin(coins[i].serializedCoin, coins[i].serializedCoinLength);
|
||||
|
||||
_coins.push_back(meta);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<CAmount, std::vector<CSparkMintMeta>> estimated = SelectSparkCoins(required, subtractFeeFromAmount > 0, _coins, mintNum);
|
||||
|
||||
SelectSparkCoinsResult* result = (SelectSparkCoinsResult*)malloc(sizeof(SelectSparkCoinsResult));
|
||||
result->length = estimated.second.size();
|
||||
result->fee = estimated.first;
|
||||
result->list = (CCSparkMintMeta*)malloc(sizeof(CCSparkMintMeta) * result->length);
|
||||
|
||||
for (int i = 0; i < estimated.second.size(); i++) {
|
||||
result->list[i].height = estimated.second[i].nHeight;
|
||||
|
||||
result->list[i].id = estimated.second[i].nId;
|
||||
|
||||
result->list[i].isUsed = estimated.second[i].isUsed;
|
||||
|
||||
result->list[i].txid = (unsigned char*)malloc(sizeof(unsigned char) * estimated.second[i].txid.size());
|
||||
memcpy(result->list[i].txid, estimated.second[i].txid.begin(), sizeof(unsigned char) * estimated.second[i].txid.size());
|
||||
|
||||
result->list[i].i = estimated.second[i].i;
|
||||
|
||||
result->list[i].dLength = estimated.second[i].d.size();
|
||||
result->list[i].d = (unsigned char*)malloc(sizeof(unsigned char) * estimated.second[i].d.size());
|
||||
memcpy(result->list[i].d, estimated.second[i].d.data(), sizeof(unsigned char) * estimated.second[i].d.size());
|
||||
|
||||
result->list[i].v = estimated.second[i].v;
|
||||
|
||||
result->list[i].nonceHexLength = estimated.second[i].k.GetHex().length();
|
||||
result->list[i].nonceHex = (char*)malloc(sizeof(char) * result->list[i].nonceHexLength);
|
||||
memcpy(result->list[i].nonceHex, estimated.second[i].k.GetHex().c_str(), sizeof(char) * result->list[i].nonceHexLength);
|
||||
|
||||
result->list[i].memoLength = estimated.second[i].memo.length();
|
||||
result->list[i].memo = (char*)malloc(sizeof(char) * result->list[i].memoLength);
|
||||
memcpy(result->list[i].memo, estimated.second[i].memo.c_str(), sizeof(char) * result->list[i].memoLength);
|
||||
|
||||
|
||||
result->list[i].serial_context = (unsigned char*)malloc(sizeof(unsigned char) * estimated.second[i].serial_context.size());
|
||||
memcpy(result->list[i].serial_context, estimated.second[i].serial_context.data(), sizeof(unsigned char) * estimated.second[i].serial_context.size());
|
||||
result->list[i].serial_contextLength = estimated.second[i].serial_context.size();
|
||||
|
||||
CDataStream coinStream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
coinStream << estimated.second[i].coin;
|
||||
result->list[i].serializedCoinLength = coinStream.size();
|
||||
result->list[i].serializedCoin = (unsigned char*)malloc(sizeof(unsigned char) * coinStream.size());
|
||||
memcpy(result->list[i].serializedCoin, coinStream.data(), coinStream.size());
|
||||
|
||||
result->list[i].type = estimated.second[i].type;
|
||||
}
|
||||
result->errorMessageLength = 0; // false/no error
|
||||
return result;
|
||||
} catch (const std::exception& e) {
|
||||
SelectSparkCoinsResult *result = (SelectSparkCoinsResult*)malloc(sizeof(SelectSparkCoinsResult));
|
||||
result->errorMessageLength = strlen(e.what());
|
||||
result->errorMessage = (char*)malloc(sizeof(char) * result->errorMessageLength);
|
||||
memcpy(result->errorMessage, e.what(), result->errorMessageLength);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
SerializedMintContextResult* serializeMintContext(
|
||||
DartInputData* inputs,
|
||||
|
||||
@@ -72,22 +72,6 @@ struct SparkSpendTransactionResult* cCreateSparkSpendTransaction(
|
||||
unsigned char* txHashSig
|
||||
);
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
struct GetSparkCoinsResult* getCoinsToSpend(
|
||||
int64_t spendAmount,
|
||||
struct CCSparkMintMeta* coins,
|
||||
int coinLength
|
||||
);
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
struct SelectSparkCoinsResult* selectSparkCoins(
|
||||
int64_t required,
|
||||
int subtractFeeFromAmount,
|
||||
struct CCSparkMintMeta* coins,
|
||||
int coinsLength,
|
||||
int mintNum
|
||||
);
|
||||
|
||||
FFI_PLUGIN_EXPORT
|
||||
struct SerializedMintContextResult* serializeMintContext(
|
||||
struct DartInputData* inputs,
|
||||
|
||||
@@ -141,26 +141,6 @@ struct CCSparkMintMeta {
|
||||
int serializedCoinLength;
|
||||
};
|
||||
|
||||
struct GetSparkCoinsResult {
|
||||
struct CCSparkMintMeta* list;
|
||||
int length;
|
||||
|
||||
int64_t changeToMint;
|
||||
|
||||
char *errorMessage;
|
||||
int errorMessageLength;
|
||||
};
|
||||
|
||||
struct SelectSparkCoinsResult {
|
||||
struct CCSparkMintMeta* list;
|
||||
int length;
|
||||
|
||||
int64_t fee;
|
||||
|
||||
char *errorMessage;
|
||||
int errorMessageLength;
|
||||
};
|
||||
|
||||
/*
|
||||
* FFI-friendly wrapper for a spark::CoverSetData.
|
||||
*
|
||||
@@ -175,8 +155,6 @@ struct CCoverSetData {
|
||||
int setId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct OutputScript {
|
||||
unsigned char *bytes;
|
||||
int length;
|
||||
|
||||
Reference in New Issue
Block a user