mirror of
https://gitlab.com/veilid/veilid.git
synced 2026-10-12 17:32:09 -05:00
Bugfixes for 0.5.7
This commit is contained in:
1 parent
76b2176926
commit
e9a95f9cd4
148 files changed
+7923
-2210
No files matched your search
@@ -18,205 +18,217 @@ import 'test_table_db.dart';
|
||||
import 'test_veilid_config.dart';
|
||||
|
||||
void main() => runWithIntegrationLog(() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(const IntegrationLogApp());
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(const IntegrationLogApp());
|
||||
|
||||
final fixture = DefaultVeilidFixture(
|
||||
programName: 'veilid_flutter integration test',
|
||||
logFixture: LogFixture.instance);
|
||||
final updateProcessorFixture =
|
||||
UpdateProcessorFixture(veilidFixture: fixture);
|
||||
final fixture = DefaultVeilidFixture(
|
||||
programName: 'veilid_flutter integration test',
|
||||
logFixture: LogFixture.instance);
|
||||
final updateProcessorFixture =
|
||||
UpdateProcessorFixture(veilidFixture: fixture);
|
||||
|
||||
// setUp(() {
|
||||
// final liveTest = Invoker.current?.liveTest;
|
||||
// print('setUp ${liveTest?.test.name}');
|
||||
// });
|
||||
// tearDown(() {
|
||||
// final liveTest = Invoker.current?.liveTest;
|
||||
// print('tearDown ${liveTest?.test.name}');
|
||||
// });
|
||||
// setUp(() {
|
||||
// final liveTest = Invoker.current?.liveTest;
|
||||
// print('setUp ${liveTest?.test.name}');
|
||||
// });
|
||||
// tearDown(() {
|
||||
// final liveTest = Invoker.current?.liveTest;
|
||||
// print('tearDown ${liveTest?.test.name}');
|
||||
// });
|
||||
|
||||
group('Uninitialized', () {
|
||||
test('veilid config defaults', testVeilidConfigDefaults, tags: ['config']);
|
||||
});
|
||||
|
||||
group('Initialized', () {
|
||||
setUpAll(fixture.setUp);
|
||||
tearDownAll(fixture.tearDown);
|
||||
setUpAll(updateProcessorFixture.setUp);
|
||||
tearDownAll(updateProcessorFixture.tearDown);
|
||||
// Fail the run if any subsystem (online/relay/route/connection/readiness) flapped
|
||||
tearDownAll(LogFixture.instance.assertNoFlapping);
|
||||
|
||||
group('Crypto', () {
|
||||
test('list cryptosystems', testListCryptoSystems, tags: ['crypto']);
|
||||
test('get cryptosystem', testGetCryptoSystems, tags: ['crypto']);
|
||||
test('get cryptosystem invalid', testGetCryptoSystemInvalid,
|
||||
tags: ['crypto']);
|
||||
test('hash and verify password', testHashAndVerifyPassword,
|
||||
tags: ['crypto']);
|
||||
test('sign and verify signature', testSignAndVerifySignature);
|
||||
test('sign and verify signatures', testSignAndVerifySignatures,
|
||||
tags: ['crypto']);
|
||||
test('generate shared secret', testGenerateSharedSecret,
|
||||
tags: ['crypto']);
|
||||
test('hpke seal and open', testHpkeSealOpen, tags: ['crypto']);
|
||||
test('kem bridge from signing keys', testKemBridgeFromSigningKeys,
|
||||
tags: ['crypto']);
|
||||
});
|
||||
|
||||
group('Table DB', () {
|
||||
test('delete table db nonexistent', testDeleteTableDbNonExistent,
|
||||
tags: ['table_db']);
|
||||
test('open delete table db', testOpenDeleteTableDb, tags: ['table_db']);
|
||||
test('open twice table db', testOpenTwiceTableDb, tags: ['table_db']);
|
||||
test('open twice table db store load', testOpenTwiceTableDbStoreLoad,
|
||||
tags: ['table_db']);
|
||||
test('open twice table db store delete load',
|
||||
testOpenTwiceTableDbStoreDeleteLoad,
|
||||
tags: ['table_db']);
|
||||
test('resize table db', testResizeTableDb, tags: ['table_db']);
|
||||
});
|
||||
|
||||
group('Protected Store', () {
|
||||
test('save load remove user secret', testSaveLoadRemoveUserSecret,
|
||||
tags: ['protected_store']);
|
||||
test('binary user secret roundtrip', testBinaryUserSecretRoundtrip,
|
||||
tags: ['protected_store']);
|
||||
test('missing user secret', testMissingUserSecret,
|
||||
tags: ['protected_store']);
|
||||
test('list user secrets', testListUserSecrets, tags: ['protected_store']);
|
||||
test('list never returns reserved keys', testListNeverReturnsReservedKeys,
|
||||
tags: ['protected_store']);
|
||||
test('reserved keys are rejected', testReservedKeysAreRejected,
|
||||
tags: ['protected_store']);
|
||||
test('delete all user secrets', testDeleteAllUserSecrets,
|
||||
tags: ['protected_store']);
|
||||
});
|
||||
|
||||
group('Attached', () {
|
||||
setUpAll(fixture.attach);
|
||||
tearDownAll(fixture.detach);
|
||||
|
||||
group('Routing Contexts', () {
|
||||
test('routing contexts', testRoutingContexts);
|
||||
test('app message loopback',
|
||||
() => testAppMessageLoopback(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_message']);
|
||||
test('app call loopback',
|
||||
() => testAppCallLoopback(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_call']);
|
||||
test('app message loopback big packets',
|
||||
() => testAppMessageLoopbackBigPackets(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_message_big']);
|
||||
test('app call loopback big packets',
|
||||
() => testAppCallLoopbackBigPackets(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_call_big']);
|
||||
group('Uninitialized', () {
|
||||
test('veilid config defaults', testVeilidConfigDefaults,
|
||||
tags: ['config']);
|
||||
});
|
||||
|
||||
for (final cryptoKind in Veilid.instance.validCryptoKinds()) {
|
||||
group('DHT $cryptoKind', () {
|
||||
final testDHT = TestDHT(cryptoKind);
|
||||
setUpAll(testDHT.setUpAll);
|
||||
tearDownAll(testDHT.tearDownAll);
|
||||
group('Initialized', () {
|
||||
setUpAll(fixture.setUp);
|
||||
tearDownAll(fixture.tearDown);
|
||||
setUpAll(updateProcessorFixture.setUp);
|
||||
tearDownAll(updateProcessorFixture.tearDown);
|
||||
// Fail the run if any subsystem (online/relay/route/connection/readiness) flapped
|
||||
tearDownAll(LogFixture.instance.assertNoFlapping);
|
||||
|
||||
test('get dht value unopened', testDHT.testGetDHTValueUnopened,
|
||||
tags: ['dht']);
|
||||
test('open dht record nonexistent no writer',
|
||||
testDHT.testOpenDHTRecordNonexistentNoWriter,
|
||||
tags: ['dht']);
|
||||
test('close dht record nonexistent',
|
||||
testDHT.testCloseDHTRecordNonexistent,
|
||||
tags: ['dht']);
|
||||
test('delete dht record nonexistent',
|
||||
testDHT.testDeleteDHTRecordNonexistent,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record simple',
|
||||
testDHT.testCreateDeleteDHTRecordSimple,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record no close',
|
||||
testDHT.testCreateDeleteDHTRecordNoClose,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record with deterministic key',
|
||||
testDHT.testCreateDHTRecordWithDeterministicKey,
|
||||
tags: ['dht']);
|
||||
test('get dht value nonexistent', testDHT.testGetDHTValueNonexistent);
|
||||
test('set get dht value', testDHT.testSetGetDHTValue, tags: ['dht']);
|
||||
test('set get dht value with owner',
|
||||
testDHT.testSetGetDHTValueWithOwner,
|
||||
tags: ['dht']);
|
||||
test('open writer dht value', testDHT.testOpenWriterDHTValue,
|
||||
tags: ['dht']);
|
||||
test('inspect dht record', testDHT.testInspectDHTRecord,
|
||||
tags: ['dht']);
|
||||
test('flush dht record', testDHT.testFlushDHTRecord, tags: ['dht']);
|
||||
group('Crypto', () {
|
||||
test('list cryptosystems', testListCryptoSystems, tags: ['crypto']);
|
||||
test('get cryptosystem', testGetCryptoSystems, tags: ['crypto']);
|
||||
test('get cryptosystem invalid', testGetCryptoSystemInvalid,
|
||||
tags: ['crypto']);
|
||||
test('hash and verify password', testHashAndVerifyPassword,
|
||||
tags: ['crypto']);
|
||||
test('sign and verify signature', testSignAndVerifySignature);
|
||||
test('sign and verify signatures', testSignAndVerifySignatures,
|
||||
tags: ['crypto']);
|
||||
test('generate shared secret', testGenerateSharedSecret,
|
||||
tags: ['crypto']);
|
||||
test('hpke seal and open', testHpkeSealOpen, tags: ['crypto']);
|
||||
test('kem bridge from signing keys', testKemBridgeFromSigningKeys,
|
||||
tags: ['crypto']);
|
||||
});
|
||||
|
||||
group('DHT Transactions $cryptoKind', () {
|
||||
final testDHTTransactions =
|
||||
TestDHTTransactions(cryptoKind, updateProcessorFixture);
|
||||
setUpAll(testDHTTransactions.setUpAll);
|
||||
tearDownAll(testDHTTransactions.tearDownAll);
|
||||
|
||||
setUp(testDHTTransactions.setUp);
|
||||
tearDown(testDHTTransactions.tearDown);
|
||||
|
||||
test('should create empty transaction and drop it explicitly',
|
||||
testDHTTransactions.testEmptyTxAndDrop,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create empty transaction and rollback',
|
||||
testDHTTransactions.testEmptyTxAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create empty transaction and commit',
|
||||
testDHTTransactions.testEmptyTxAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, and rollback',
|
||||
testDHTTransactions.testTxAddSetsAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, and commit',
|
||||
testDHTTransactions.testTxAddSetsAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should extend transaction with new record and commit',
|
||||
testDHTTransactions.testTxExtendAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should extend transaction with new record and rollback',
|
||||
testDHTTransactions.testTxExtendAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, gets, and commit',
|
||||
testDHTTransactions.testTxAddSetsGetsAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test(
|
||||
'should create empty transaction, fail non-transactional sets and'
|
||||
' then rollback',
|
||||
testDHTTransactions.testTxFailNonTxSetsAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test(
|
||||
'should create transaction, inspect, add sets to subkey 1, '
|
||||
' inspect and commit. Then a new transaction inspect, and gets, '
|
||||
'and commit',
|
||||
testDHTTransactions.testTxInspectAddInspectCommit,
|
||||
tags: ['dht_transactions']);
|
||||
group('Table DB', () {
|
||||
test('delete table db nonexistent', testDeleteTableDbNonExistent,
|
||||
tags: ['table_db']);
|
||||
test('open delete table db', testOpenDeleteTableDb,
|
||||
tags: ['table_db']);
|
||||
test('open twice table db', testOpenTwiceTableDb, tags: ['table_db']);
|
||||
test('open twice table db store load', testOpenTwiceTableDbStoreLoad,
|
||||
tags: ['table_db']);
|
||||
test('open twice table db store delete load',
|
||||
testOpenTwiceTableDbStoreDeleteLoad,
|
||||
tags: ['table_db']);
|
||||
test('resize table db', testResizeTableDb, tags: ['table_db']);
|
||||
});
|
||||
|
||||
group('Veilid DHT Transactions Full $cryptoKind', () {
|
||||
final testDHTTransactionsFull = TestDHTTransactionsFull(cryptoKind);
|
||||
setUpAll(testDHTTransactionsFull.setUpAll);
|
||||
tearDownAll(testDHTTransactionsFull.tearDownAll);
|
||||
|
||||
setUp(testDHTTransactionsFull.setUp);
|
||||
tearDown(testDHTTransactionsFull.tearDown);
|
||||
|
||||
test('should create empty transaction, inspect, add gets and commit',
|
||||
testDHTTransactionsFull.testEmptyTxInspectGetsAndCommit,
|
||||
timeout: const Timeout(Duration(seconds: 120)), tags: ['stress']);
|
||||
test(
|
||||
'should create transaction, fill all records, commit, and then'
|
||||
' get all records and rollback',
|
||||
testDHTTransactionsFull.testTxFillCommitTxGetRollback,
|
||||
timeout: const Timeout(Duration(seconds: 300)),
|
||||
tags: ['stress']);
|
||||
group('Protected Store', () {
|
||||
test('save load remove user secret', testSaveLoadRemoveUserSecret,
|
||||
tags: ['protected_store']);
|
||||
test('binary user secret roundtrip', testBinaryUserSecretRoundtrip,
|
||||
tags: ['protected_store']);
|
||||
test('missing user secret', testMissingUserSecret,
|
||||
tags: ['protected_store']);
|
||||
test('list user secrets', testListUserSecrets,
|
||||
tags: ['protected_store']);
|
||||
test('list never returns reserved keys',
|
||||
testListNeverReturnsReservedKeys,
|
||||
tags: ['protected_store']);
|
||||
test('reserved keys are rejected', testReservedKeysAreRejected,
|
||||
tags: ['protected_store']);
|
||||
test('delete all user secrets', testDeleteAllUserSecrets,
|
||||
tags: ['protected_store']);
|
||||
});
|
||||
}
|
||||
|
||||
group('Attached', () {
|
||||
setUpAll(fixture.attach);
|
||||
tearDownAll(fixture.detach);
|
||||
|
||||
group('Routing Contexts', () {
|
||||
test('routing contexts', testRoutingContexts);
|
||||
test('app message loopback',
|
||||
() => testAppMessageLoopback(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_message']);
|
||||
test('app call loopback',
|
||||
() => testAppCallLoopback(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_call']);
|
||||
test('app message loopback big packets',
|
||||
() => testAppMessageLoopbackBigPackets(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_message_big']);
|
||||
test('app call loopback big packets',
|
||||
() => testAppCallLoopbackBigPackets(fixture.updateStream),
|
||||
tags: ['routing_context', 'app_call_big']);
|
||||
});
|
||||
|
||||
for (final cryptoKind in Veilid.instance.validCryptoKinds()) {
|
||||
group('DHT $cryptoKind', () {
|
||||
final testDHT = TestDHT(cryptoKind);
|
||||
setUpAll(testDHT.setUpAll);
|
||||
tearDownAll(testDHT.tearDownAll);
|
||||
|
||||
test('get dht value unopened', testDHT.testGetDHTValueUnopened,
|
||||
tags: ['dht']);
|
||||
test('open dht record nonexistent no writer',
|
||||
testDHT.testOpenDHTRecordNonexistentNoWriter,
|
||||
tags: ['dht']);
|
||||
test('close dht record nonexistent',
|
||||
testDHT.testCloseDHTRecordNonexistent,
|
||||
tags: ['dht']);
|
||||
test('delete dht record nonexistent',
|
||||
testDHT.testDeleteDHTRecordNonexistent,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record simple',
|
||||
testDHT.testCreateDeleteDHTRecordSimple,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record no close',
|
||||
testDHT.testCreateDeleteDHTRecordNoClose,
|
||||
tags: ['dht']);
|
||||
test('create delete dht record with deterministic key',
|
||||
testDHT.testCreateDHTRecordWithDeterministicKey,
|
||||
tags: ['dht']);
|
||||
test('get dht value nonexistent',
|
||||
testDHT.testGetDHTValueNonexistent);
|
||||
test('set get dht value', testDHT.testSetGetDHTValue,
|
||||
tags: ['dht']);
|
||||
test('set get dht value with owner',
|
||||
testDHT.testSetGetDHTValueWithOwner,
|
||||
tags: ['dht']);
|
||||
test('open writer dht value', testDHT.testOpenWriterDHTValue,
|
||||
tags: ['dht']);
|
||||
test('inspect dht record', testDHT.testInspectDHTRecord,
|
||||
tags: ['dht']);
|
||||
test('min seqnum dht record', testDHT.testMinSeqnumDHTRecord,
|
||||
tags: ['dht']);
|
||||
test('flush dht record', testDHT.testFlushDHTRecord,
|
||||
tags: ['dht']);
|
||||
});
|
||||
|
||||
group('DHT Transactions $cryptoKind', () {
|
||||
final testDHTTransactions =
|
||||
TestDHTTransactions(cryptoKind, updateProcessorFixture);
|
||||
setUpAll(testDHTTransactions.setUpAll);
|
||||
tearDownAll(testDHTTransactions.tearDownAll);
|
||||
|
||||
setUp(testDHTTransactions.setUp);
|
||||
tearDown(testDHTTransactions.tearDown);
|
||||
|
||||
test('should create empty transaction and drop it explicitly',
|
||||
testDHTTransactions.testEmptyTxAndDrop,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create empty transaction and rollback',
|
||||
testDHTTransactions.testEmptyTxAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create empty transaction and commit',
|
||||
testDHTTransactions.testEmptyTxAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, and rollback',
|
||||
testDHTTransactions.testTxAddSetsAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, and commit',
|
||||
testDHTTransactions.testTxAddSetsAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should extend transaction with new record and commit',
|
||||
testDHTTransactions.testTxExtendAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test('should extend transaction with new record and rollback',
|
||||
testDHTTransactions.testTxExtendAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test('should create transaction, add sets, gets, and commit',
|
||||
testDHTTransactions.testTxAddSetsGetsAndCommit,
|
||||
tags: ['dht_transactions']);
|
||||
test(
|
||||
'should create empty transaction, fail non-transactional sets and'
|
||||
' then rollback',
|
||||
testDHTTransactions.testTxFailNonTxSetsAndRollback,
|
||||
tags: ['dht_transactions']);
|
||||
test(
|
||||
'should create transaction, inspect, add sets to subkey 1, '
|
||||
' inspect and commit. Then a new transaction inspect, and gets, '
|
||||
'and commit',
|
||||
testDHTTransactions.testTxInspectAddInspectCommit,
|
||||
tags: ['dht_transactions']);
|
||||
});
|
||||
|
||||
group('Veilid DHT Transactions Full $cryptoKind', () {
|
||||
final testDHTTransactionsFull =
|
||||
TestDHTTransactionsFull(cryptoKind);
|
||||
setUpAll(testDHTTransactionsFull.setUpAll);
|
||||
tearDownAll(testDHTTransactionsFull.tearDownAll);
|
||||
|
||||
setUp(testDHTTransactionsFull.setUp);
|
||||
tearDown(testDHTTransactionsFull.tearDown);
|
||||
|
||||
test(
|
||||
'should create empty transaction, inspect, add gets and commit',
|
||||
testDHTTransactionsFull.testEmptyTxInspectGetsAndCommit,
|
||||
timeout: const Timeout(Duration(seconds: 120)),
|
||||
tags: ['stress']);
|
||||
test(
|
||||
'should create transaction, fill all records, commit, and then'
|
||||
' get all records and rollback',
|
||||
testDHTTransactionsFull.testTxFillCommitTxGetRollback,
|
||||
timeout: const Timeout(Duration(seconds: 300)),
|
||||
tags: ['stress']);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -122,8 +122,7 @@ Future<void> testHpkeSealOpen() async {
|
||||
expect(await cs.hpkeOpen(kkp1.secret, aad, sealed), equals(plaintext));
|
||||
|
||||
// empty aad and empty plaintext round-trip
|
||||
final sealedEmpty =
|
||||
await cs.hpkeSeal(kkp1.key, Uint8List(0), Uint8List(0));
|
||||
final sealedEmpty = await cs.hpkeSeal(kkp1.key, Uint8List(0), Uint8List(0));
|
||||
expect(await cs.hpkeOpen(kkp1.secret, Uint8List(0), sealedEmpty),
|
||||
equals(Uint8List(0)));
|
||||
|
||||
|
||||
@@ -12,6 +12,17 @@ class TestDHT {
|
||||
|
||||
TestDHT(this.cryptoKind);
|
||||
|
||||
// A closing write has no next write to recover with, so it reports TryAgain
|
||||
static final _closingWriteRetry = RetryStrategy(
|
||||
timeout: const Duration(seconds: 30),
|
||||
rules: [
|
||||
RetryRule.delay(
|
||||
matches: (e) => e is VeilidAPIExceptionTryAgain,
|
||||
delay: const Duration(milliseconds: 250),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Future<void> setUpAll() async {
|
||||
routingContext = await Veilid.instance.routingContext();
|
||||
}
|
||||
@@ -297,6 +308,50 @@ class TestDHT {
|
||||
await routingContext.deleteDHTRecord(rec.key);
|
||||
}
|
||||
|
||||
Future<void> testMinSeqnumDHTRecord() async {
|
||||
final rec = await routingContext.createDHTRecord(
|
||||
cryptoKind, const DHTSchema.dflt(oCnt: 1));
|
||||
|
||||
const noOffline = SetDHTValueOptions(allowOffline: false);
|
||||
final va = utf8.encode('Qwertyuiop Asdfghjkl Zxcvbnm');
|
||||
final vb = utf8.encode('1234567890');
|
||||
|
||||
// maxSeqnum - 1 leaves exactly one write
|
||||
expect(
|
||||
await routingContext.setDHTValue(rec.key, 0, va,
|
||||
options: noOffline.copyWith(minSeqnum: ValueData.maxSeqnum - 1)),
|
||||
isNull);
|
||||
|
||||
var rr = await routingContext.inspectDHTRecord(rec.key);
|
||||
expect(rr.localSeqs, equals([ValueData.maxSeqnum - 1]));
|
||||
|
||||
expect(
|
||||
await _closingWriteRetry.retry(() =>
|
||||
routingContext.setDHTValue(rec.key, 0, vb, options: noOffline)),
|
||||
isNull);
|
||||
|
||||
rr = await routingContext.inspectDHTRecord(rec.key);
|
||||
expect(rr.localSeqs, equals([ValueData.maxSeqnum]));
|
||||
|
||||
// Nothing writes after maxSeqnum
|
||||
await expectLater(
|
||||
routingContext.setDHTValue(rec.key, 0, va, options: noOffline),
|
||||
throwsA(isA<VeilidAPIExceptionGeneric>()));
|
||||
|
||||
// A resend at the same minimum reuses the seqnum instead of failing
|
||||
expect(
|
||||
await _closingWriteRetry.retry(() => routingContext.setDHTValue(
|
||||
rec.key, 0, vb,
|
||||
options: noOffline.copyWith(minSeqnum: ValueData.maxSeqnum))),
|
||||
isNull);
|
||||
|
||||
rr = await routingContext.inspectDHTRecord(rec.key);
|
||||
expect(rr.localSeqs, equals([ValueData.maxSeqnum]));
|
||||
|
||||
await routingContext.closeDHTRecord(rec.key);
|
||||
await routingContext.deleteDHTRecord(rec.key);
|
||||
}
|
||||
|
||||
Future<void> testFlushDHTRecord() async {
|
||||
final rec = await routingContext.createDHTRecord(
|
||||
cryptoKind, const DHTSchema.dflt(oCnt: 1));
|
||||
|
||||
@@ -112,13 +112,15 @@ class TestDHTTransactionsFull {
|
||||
// Commit
|
||||
final startCommit = Veilid.instance.now();
|
||||
await tx.commit();
|
||||
debugPrint('commit transaction: ${Veilid.instance.now().diff(startCommit)}');
|
||||
debugPrint(
|
||||
'commit transaction: ${Veilid.instance.now().diff(startCommit)}');
|
||||
|
||||
// Transaction 2
|
||||
final startCommit2 = Veilid.instance.now();
|
||||
final tx2 = await Veilid.instance.transactDHTRecords(dhtRecords);
|
||||
expect(tx2, isInstanceOf<VeilidDHTTransaction>());
|
||||
debugPrint('begin transaction 2: ${Veilid.instance.now().diff(startCommit2)}');
|
||||
debugPrint(
|
||||
'begin transaction 2: ${Veilid.instance.now().diff(startCommit2)}');
|
||||
|
||||
// Gets
|
||||
for (var subkey = 0; subkey < dhtSubkeyCount; subkey++) {
|
||||
|
||||
@@ -19,8 +19,7 @@ Future<void> testSaveLoadRemoveUserSecret() async {
|
||||
await _cleanup();
|
||||
|
||||
// Saving a new secret reports that nothing was there before.
|
||||
expect(
|
||||
await Veilid.instance.saveUserSecret(testKey, utf8.encode('hello')),
|
||||
expect(await Veilid.instance.saveUserSecret(testKey, utf8.encode('hello')),
|
||||
isFalse);
|
||||
expect(utf8.decode((await Veilid.instance.loadUserSecret(testKey))!),
|
||||
equals('hello'));
|
||||
@@ -54,7 +53,8 @@ Future<void> testBinaryUserSecretRoundtrip() async {
|
||||
|
||||
Future<void> testMissingUserSecret() async {
|
||||
expect(await Veilid.instance.loadUserSecret('__dart_never_stored'), isNull);
|
||||
expect(await Veilid.instance.removeUserSecret('__dart_never_stored'), isFalse);
|
||||
expect(
|
||||
await Veilid.instance.removeUserSecret('__dart_never_stored'), isFalse);
|
||||
}
|
||||
|
||||
Future<void> testListUserSecrets() async {
|
||||
@@ -118,8 +118,8 @@ Future<void> testDeleteAllUserSecrets() async {
|
||||
}
|
||||
|
||||
// The store is still usable afterwards.
|
||||
expect(await Veilid.instance.saveUserSecret(testKey, utf8.encode('c')),
|
||||
isFalse);
|
||||
expect(
|
||||
await Veilid.instance.saveUserSecret(testKey, utf8.encode('c')), isFalse);
|
||||
keys = await Veilid.instance.listUserSecrets();
|
||||
expect(keys, contains(testKey));
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ void main() {
|
||||
// Verify that platform version is retrieved.
|
||||
expect(
|
||||
find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is Text && widget.data!.startsWith('Running on:'),
|
||||
(widget) => widget is Text && widget.data!.startsWith('Running on:'),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Builds veilid-flutter/rust as the code asset lib/veilid_ffi.dart resolves against.
|
||||
// `assetName` below and that file's @DefaultAsset must move together.
|
||||
|
||||
import 'package:code_assets/code_assets.dart';
|
||||
import 'package:hooks/hooks.dart';
|
||||
import 'package:native_toolchain_rust/native_toolchain_rust.dart';
|
||||
|
||||
@@ -24,41 +24,46 @@ Future<VeilidConfig> getDefaultVeilidConfig({
|
||||
final defaultConfigStr = Veilid.instance.defaultVeilidConfig();
|
||||
final defaultConfig = VeilidConfig.fromJson(jsonDecode(defaultConfigStr));
|
||||
return defaultConfig.copyWith(
|
||||
programName: programName,
|
||||
namespace: namespace,
|
||||
tableStore: defaultConfig.tableStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
'table_store'),
|
||||
programName: programName,
|
||||
namespace: namespace,
|
||||
tableStore: defaultConfig.tableStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join(
|
||||
(await getApplicationSupportDirectory()).absolute.path,
|
||||
'table_store',
|
||||
),
|
||||
),
|
||||
blockStore: defaultConfig.blockStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join(
|
||||
(await getApplicationSupportDirectory()).absolute.path,
|
||||
'block_store',
|
||||
),
|
||||
),
|
||||
protectedStore: defaultConfig.protectedStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join(
|
||||
(await getApplicationSupportDirectory()).absolute.path,
|
||||
'protected_store',
|
||||
),
|
||||
deviceEncryptionKeyPassword: deviceEncryptionKeyPassword,
|
||||
newDeviceEncryptionKeyPassword: newDeviceEncryptionKeyPassword,
|
||||
),
|
||||
network: defaultConfig.network.copyWith(
|
||||
networkKeyPassword: networkKeyPassword,
|
||||
routingTable: defaultConfig.network.routingTable.copyWith(
|
||||
bootstrap: bootstrap.isNotEmpty
|
||||
? bootstrap.split(',')
|
||||
: defaultConfig.network.routingTable.bootstrap,
|
||||
bootstrapKeys: bootstrapKeys != null
|
||||
? bootstrapKeys.isNotEmpty
|
||||
? bootstrapKeys.split(',').map(PublicKey.fromString).toList()
|
||||
: []
|
||||
: defaultConfig.network.routingTable.bootstrapKeys,
|
||||
),
|
||||
blockStore: defaultConfig.blockStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
'block_store'),
|
||||
),
|
||||
protectedStore: defaultConfig.protectedStore.copyWith(
|
||||
directory: isWeb
|
||||
? ''
|
||||
: p.join((await getApplicationSupportDirectory()).absolute.path,
|
||||
'protected_store'),
|
||||
deviceEncryptionKeyPassword: deviceEncryptionKeyPassword,
|
||||
newDeviceEncryptionKeyPassword: newDeviceEncryptionKeyPassword,
|
||||
),
|
||||
network: defaultConfig.network.copyWith(
|
||||
networkKeyPassword: networkKeyPassword,
|
||||
routingTable: defaultConfig.network.routingTable.copyWith(
|
||||
bootstrap: bootstrap.isNotEmpty
|
||||
? bootstrap.split(',')
|
||||
: defaultConfig.network.routingTable.bootstrap,
|
||||
bootstrapKeys: bootstrapKeys != null
|
||||
? bootstrapKeys.isNotEmpty
|
||||
? bootstrapKeys
|
||||
.split(',')
|
||||
.map(PublicKey.fromString)
|
||||
.toList()
|
||||
: []
|
||||
: defaultConfig.network.routingTable.bootstrapKeys),
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -27,8 +27,9 @@ extension VeilidProcessorRetry on VeilidProcessorInterface {
|
||||
if (processorConnectionState.isPublicInternetReady) {
|
||||
return;
|
||||
}
|
||||
var stream = streamProcessorConnectionState()
|
||||
.where((s) => s.isPublicInternetReady);
|
||||
var stream = streamProcessorConnectionState().where(
|
||||
(s) => s.isPublicInternetReady,
|
||||
);
|
||||
if (timeout != null) {
|
||||
stream = stream.timeout(timeout);
|
||||
}
|
||||
@@ -50,10 +51,7 @@ extension VeilidProcessorRetry on VeilidProcessorInterface {
|
||||
/// Run [closure], retrying VeilidAPI transients per [strategy] (default
|
||||
/// [VeilidAPIRetryStrategy], waiting on network readiness before a tryAgain
|
||||
/// retry).
|
||||
Future<T> retry<T>(
|
||||
Future<T> Function() closure, {
|
||||
RetryStrategy? strategy,
|
||||
}) =>
|
||||
Future<T> retry<T>(Future<T> Function() closure, {RetryStrategy? strategy}) =>
|
||||
(strategy ??
|
||||
VeilidAPIRetryStrategy(
|
||||
tryAgainRetry: (attemptNumber) async {
|
||||
|
||||
@@ -21,19 +21,16 @@ class RetryRule {
|
||||
|
||||
/// Retry up to [maxAttempts] times (null = unbounded), waiting [delay] (or
|
||||
/// not, if null) between tries.
|
||||
RetryRule.delay({
|
||||
required this.matches,
|
||||
int? maxAttempts,
|
||||
Duration? delay,
|
||||
}) : beforeRetry = ((n) async {
|
||||
if (maxAttempts != null && n >= maxAttempts) {
|
||||
return false;
|
||||
}
|
||||
if (delay != null) {
|
||||
await Future<void>.delayed(delay);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
RetryRule.delay({required this.matches, int? maxAttempts, Duration? delay})
|
||||
: beforeRetry = ((n) async {
|
||||
if (maxAttempts != null && n >= maxAttempts) {
|
||||
return false;
|
||||
}
|
||||
if (delay != null) {
|
||||
await Future<void>.delayed(delay);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
/// Retry up to [maxAttempts] times (null = unbounded), awaiting [wait] (e.g.
|
||||
/// network readiness) between tries.
|
||||
@@ -42,20 +39,19 @@ class RetryRule {
|
||||
int? maxAttempts,
|
||||
required Future<void> Function() wait,
|
||||
}) : beforeRetry = ((n) async {
|
||||
if (maxAttempts != null && n >= maxAttempts) {
|
||||
return false;
|
||||
}
|
||||
await wait();
|
||||
return true;
|
||||
});
|
||||
if (maxAttempts != null && n >= maxAttempts) {
|
||||
return false;
|
||||
}
|
||||
await wait();
|
||||
return true;
|
||||
});
|
||||
|
||||
/// A copy whose action is [chain], which receives the attempt number and this
|
||||
/// rule's current action so it can do its own work and defer to it, e.g.
|
||||
/// `rule.withBeforeRetry((n, prev) async { record(); return prev(n); })`.
|
||||
RetryRule withBeforeRetry(
|
||||
Future<bool> Function(int attemptNumber, RetryAction previous) chain,
|
||||
) =>
|
||||
RetryRule(matches: matches, beforeRetry: (n) => chain(n, beforeRetry));
|
||||
) => RetryRule(matches: matches, beforeRetry: (n) => chain(n, beforeRetry));
|
||||
|
||||
/// A copy that runs [onRetry] (e.g. telemetry) before this rule's action, or
|
||||
/// this rule unchanged if [onRetry] is null.
|
||||
@@ -127,8 +123,8 @@ class RetryStrategy {
|
||||
}
|
||||
|
||||
/// VeilidAPI-level policy: retry the transients that clear once online. Each
|
||||
/// rule's action defaults to a bounded fixed delay; override either to change
|
||||
/// the wait (e.g. block on network readiness) or add telemetry.
|
||||
/// rule's action defaults to a bounded doubling delay; override either to
|
||||
/// change the wait (e.g. block on network readiness) or add telemetry.
|
||||
class VeilidAPIRetryStrategy extends RetryStrategy {
|
||||
/// [tryAgainRetry] handles [VeilidAPIExceptionTryAgain]; [transientRetry]
|
||||
/// handles timeout and no-connection errors. Either defaults to
|
||||
@@ -139,27 +135,30 @@ class VeilidAPIRetryStrategy extends RetryStrategy {
|
||||
RetryAction? transientRetry,
|
||||
Duration? timeout,
|
||||
}) : super(
|
||||
rules: [
|
||||
RetryRule(
|
||||
matches: (e) => e is VeilidAPIExceptionTryAgain,
|
||||
beforeRetry: tryAgainRetry ?? defaultRetry,
|
||||
),
|
||||
RetryRule(
|
||||
matches: (e) =>
|
||||
e is VeilidAPIExceptionTimeout ||
|
||||
e is VeilidAPIExceptionNoConnection,
|
||||
beforeRetry: transientRetry ?? defaultRetry,
|
||||
),
|
||||
],
|
||||
timeout: timeout,
|
||||
);
|
||||
rules: [
|
||||
RetryRule(
|
||||
matches: (e) => e is VeilidAPIExceptionTryAgain,
|
||||
beforeRetry: tryAgainRetry ?? defaultRetry,
|
||||
),
|
||||
RetryRule(
|
||||
matches: (e) =>
|
||||
e is VeilidAPIExceptionTimeout ||
|
||||
e is VeilidAPIExceptionNoConnection,
|
||||
beforeRetry: transientRetry ?? defaultRetry,
|
||||
),
|
||||
],
|
||||
timeout: timeout,
|
||||
);
|
||||
|
||||
/// Up to 3 tries, 250ms apart.
|
||||
/// Up to 3 tries, waiting 500ms then 1s. The delay doubles because a flat one
|
||||
/// re-offers the whole load to a congested network at once.
|
||||
static Future<bool> defaultRetry(int attemptNumber) async {
|
||||
if (attemptNumber >= 3) {
|
||||
return false;
|
||||
}
|
||||
await Future<void>.delayed(const Duration(milliseconds: 250));
|
||||
await Future<void>.delayed(
|
||||
Duration(milliseconds: 250 * (1 << attemptNumber)),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -52,22 +52,30 @@ abstract class VeilidAPIException implements Exception {
|
||||
case 'Unimplemented':
|
||||
{
|
||||
return VeilidAPIExceptionUnimplemented(
|
||||
json['unimplemented']! as String);
|
||||
json['unimplemented']! as String,
|
||||
);
|
||||
}
|
||||
case 'ParseError':
|
||||
{
|
||||
return VeilidAPIExceptionParseError(
|
||||
json['message']! as String, json['value']! as String);
|
||||
json['message']! as String,
|
||||
json['value']! as String,
|
||||
);
|
||||
}
|
||||
case 'InvalidArgument':
|
||||
{
|
||||
return VeilidAPIExceptionInvalidArgument(json['context']! as String,
|
||||
json['argument']! as String, json['value']! as String);
|
||||
return VeilidAPIExceptionInvalidArgument(
|
||||
json['context']! as String,
|
||||
json['argument']! as String,
|
||||
json['value']! as String,
|
||||
);
|
||||
}
|
||||
case 'MissingArgument':
|
||||
{
|
||||
return VeilidAPIExceptionMissingArgument(
|
||||
json['context']! as String, json['argument']! as String);
|
||||
json['context']! as String,
|
||||
json['argument']! as String,
|
||||
);
|
||||
}
|
||||
case 'Generic':
|
||||
{
|
||||
@@ -76,12 +84,14 @@ abstract class VeilidAPIException implements Exception {
|
||||
case 'TransactionNotFound':
|
||||
{
|
||||
return VeilidAPIExceptionTransactionNotFound(
|
||||
json['message']! as String);
|
||||
json['message']! as String,
|
||||
);
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw VeilidAPIExceptionInternal(
|
||||
"Invalid VeilidAPIException type: ${json['kind']! as String}");
|
||||
"Invalid VeilidAPIException type: ${json['kind']! as String}",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,10 +271,14 @@ class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
|
||||
|
||||
/// Construct with the calling context, argument name, and rejected value.
|
||||
const VeilidAPIExceptionInvalidArgument(
|
||||
this.context, this.argument, this.value);
|
||||
this.context,
|
||||
this.argument,
|
||||
this.value,
|
||||
);
|
||||
|
||||
@override
|
||||
String toString() => 'VeilidAPIException: InvalidArgument'
|
||||
String toString() =>
|
||||
'VeilidAPIException: InvalidArgument'
|
||||
' ($context:$argument)\n value: $value';
|
||||
|
||||
@override
|
||||
|
||||
@@ -105,7 +105,9 @@ sealed class VeilidFFIConfigLogging with _$VeilidFFIConfigLogging {
|
||||
VeilidFFIConfigLoggingOtlp otlp,
|
||||
@Default(VeilidFFIConfigLoggingFlame(enabled: false, path: ''))
|
||||
VeilidFFIConfigLoggingFlame flame,
|
||||
@Default(VeilidFFIConfigLoggingStats(enabled: false, intervalSecs: 10, path: ''))
|
||||
@Default(
|
||||
VeilidFFIConfigLoggingStats(enabled: false, intervalSecs: 10, path: ''),
|
||||
)
|
||||
VeilidFFIConfigLoggingStats stats,
|
||||
}) = _VeilidFFIConfigLogging;
|
||||
|
||||
@@ -385,9 +387,8 @@ sealed class VeilidConfigDHT with _$VeilidConfigDHT {
|
||||
/// RPC configuration.
|
||||
@freezed
|
||||
sealed class VeilidConfigRPC with _$VeilidConfigRPC {
|
||||
const factory VeilidConfigRPC({
|
||||
required int defaultRouteHopCount,
|
||||
}) = _VeilidConfigRPC;
|
||||
const factory VeilidConfigRPC({required int defaultRouteHopCount}) =
|
||||
_VeilidConfigRPC;
|
||||
|
||||
factory VeilidConfigRPC.fromJson(dynamic json) =>
|
||||
_$VeilidConfigRPCFromJson(json as Map<String, dynamic>);
|
||||
@@ -424,17 +425,16 @@ enum VeilidConfigAddressType {
|
||||
|
||||
/// Parse from its JSON name (`IPV4`/`IPV6`).
|
||||
factory VeilidConfigAddressType.fromJson(dynamic j) => switch (j as String) {
|
||||
'IPV4' => VeilidConfigAddressType.ipv4,
|
||||
'IPV6' => VeilidConfigAddressType.ipv6,
|
||||
_ =>
|
||||
throw ArgumentError.value(j, 'j', 'invalid VeilidConfigAddressType'),
|
||||
};
|
||||
'IPV4' => VeilidConfigAddressType.ipv4,
|
||||
'IPV6' => VeilidConfigAddressType.ipv6,
|
||||
_ => throw ArgumentError.value(j, 'j', 'invalid VeilidConfigAddressType'),
|
||||
};
|
||||
|
||||
/// The JSON name (`IPV4`/`IPV6`).
|
||||
String toJson() => switch (this) {
|
||||
VeilidConfigAddressType.ipv4 => 'IPV4',
|
||||
VeilidConfigAddressType.ipv6 => 'IPV6',
|
||||
};
|
||||
VeilidConfigAddressType.ipv4 => 'IPV4',
|
||||
VeilidConfigAddressType.ipv6 => 'IPV6',
|
||||
};
|
||||
}
|
||||
|
||||
////////////
|
||||
@@ -514,8 +514,8 @@ enum VeilidConfigProtectedStoreBackend {
|
||||
/// WebExtension storage.
|
||||
extensionStorage;
|
||||
|
||||
// /// Delegate to a registered secret-resolver callback.
|
||||
// callback;
|
||||
// /// Delegate to a registered secret-resolver callback.
|
||||
// callback;
|
||||
|
||||
/// Parse from its JSON (PascalCase) name.
|
||||
factory VeilidConfigProtectedStoreBackend.fromJson(dynamic j) =>
|
||||
@@ -566,9 +566,8 @@ sealed class VeilidConfigCapabilities with _$VeilidConfigCapabilities {
|
||||
/// Internal "footgun" UDP tuning. See [VeilidConfigInternal].
|
||||
@freezed
|
||||
sealed class VeilidConfigInternalUDP with _$VeilidConfigInternalUDP {
|
||||
const factory VeilidConfigInternalUDP({
|
||||
required int socketPoolSize,
|
||||
}) = _VeilidConfigInternalUDP;
|
||||
const factory VeilidConfigInternalUDP({required int socketPoolSize}) =
|
||||
_VeilidConfigInternalUDP;
|
||||
|
||||
factory VeilidConfigInternalUDP.fromJson(dynamic json) =>
|
||||
_$VeilidConfigInternalUDPFromJson(json as Map<String, dynamic>);
|
||||
@@ -640,6 +639,7 @@ sealed class VeilidConfigInternalDHT with _$VeilidConfigInternalDHT {
|
||||
sealed class VeilidConfigInternalNetwork with _$VeilidConfigInternalNetwork {
|
||||
const factory VeilidConfigInternalNetwork({
|
||||
required int connectionInitialTimeoutMs,
|
||||
required int singleSendTimeoutMs,
|
||||
required int connectionInactivityTimeoutMs,
|
||||
required int maxConnectionsPerIp4,
|
||||
required int maxConnectionsPerIp6Prefix,
|
||||
|
||||
@@ -9119,7 +9119,7 @@ as int,
|
||||
/// @nodoc
|
||||
mixin _$VeilidConfigInternalNetwork implements DiagnosticableTreeMixin {
|
||||
|
||||
int get connectionInitialTimeoutMs; int get connectionInactivityTimeoutMs; int get maxConnectionsPerIp4; int get maxConnectionsPerIp6Prefix; int get maxConnectionsPerIp6PrefixSize; int get maxConnectionFrequencyPerMin; int get clientAllowlistTimeoutMs; int get reverseConnectionReceiptTimeMs; int get holePunchReceiptTimeMs; int get restrictedNatRetries; VeilidConfigInternalRPC get rpc; VeilidConfigInternalDHT get dht; VeilidConfigInternalProtocol get protocol;
|
||||
int get connectionInitialTimeoutMs; int get singleSendTimeoutMs; int get connectionInactivityTimeoutMs; int get maxConnectionsPerIp4; int get maxConnectionsPerIp6Prefix; int get maxConnectionsPerIp6PrefixSize; int get maxConnectionFrequencyPerMin; int get clientAllowlistTimeoutMs; int get reverseConnectionReceiptTimeMs; int get holePunchReceiptTimeMs; int get restrictedNatRetries; VeilidConfigInternalRPC get rpc; VeilidConfigInternalDHT get dht; VeilidConfigInternalProtocol get protocol;
|
||||
/// Create a copy of VeilidConfigInternalNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -9133,21 +9133,21 @@ $VeilidConfigInternalNetworkCopyWith<VeilidConfigInternalNetwork> get copyWith =
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'VeilidConfigInternalNetwork'))
|
||||
..add(DiagnosticsProperty('connectionInitialTimeoutMs', connectionInitialTimeoutMs))..add(DiagnosticsProperty('connectionInactivityTimeoutMs', connectionInactivityTimeoutMs))..add(DiagnosticsProperty('maxConnectionsPerIp4', maxConnectionsPerIp4))..add(DiagnosticsProperty('maxConnectionsPerIp6Prefix', maxConnectionsPerIp6Prefix))..add(DiagnosticsProperty('maxConnectionsPerIp6PrefixSize', maxConnectionsPerIp6PrefixSize))..add(DiagnosticsProperty('maxConnectionFrequencyPerMin', maxConnectionFrequencyPerMin))..add(DiagnosticsProperty('clientAllowlistTimeoutMs', clientAllowlistTimeoutMs))..add(DiagnosticsProperty('reverseConnectionReceiptTimeMs', reverseConnectionReceiptTimeMs))..add(DiagnosticsProperty('holePunchReceiptTimeMs', holePunchReceiptTimeMs))..add(DiagnosticsProperty('restrictedNatRetries', restrictedNatRetries))..add(DiagnosticsProperty('rpc', rpc))..add(DiagnosticsProperty('dht', dht))..add(DiagnosticsProperty('protocol', protocol));
|
||||
..add(DiagnosticsProperty('connectionInitialTimeoutMs', connectionInitialTimeoutMs))..add(DiagnosticsProperty('singleSendTimeoutMs', singleSendTimeoutMs))..add(DiagnosticsProperty('connectionInactivityTimeoutMs', connectionInactivityTimeoutMs))..add(DiagnosticsProperty('maxConnectionsPerIp4', maxConnectionsPerIp4))..add(DiagnosticsProperty('maxConnectionsPerIp6Prefix', maxConnectionsPerIp6Prefix))..add(DiagnosticsProperty('maxConnectionsPerIp6PrefixSize', maxConnectionsPerIp6PrefixSize))..add(DiagnosticsProperty('maxConnectionFrequencyPerMin', maxConnectionFrequencyPerMin))..add(DiagnosticsProperty('clientAllowlistTimeoutMs', clientAllowlistTimeoutMs))..add(DiagnosticsProperty('reverseConnectionReceiptTimeMs', reverseConnectionReceiptTimeMs))..add(DiagnosticsProperty('holePunchReceiptTimeMs', holePunchReceiptTimeMs))..add(DiagnosticsProperty('restrictedNatRetries', restrictedNatRetries))..add(DiagnosticsProperty('rpc', rpc))..add(DiagnosticsProperty('dht', dht))..add(DiagnosticsProperty('protocol', protocol));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidConfigInternalNetwork&&(identical(other.connectionInitialTimeoutMs, connectionInitialTimeoutMs) || other.connectionInitialTimeoutMs == connectionInitialTimeoutMs)&&(identical(other.connectionInactivityTimeoutMs, connectionInactivityTimeoutMs) || other.connectionInactivityTimeoutMs == connectionInactivityTimeoutMs)&&(identical(other.maxConnectionsPerIp4, maxConnectionsPerIp4) || other.maxConnectionsPerIp4 == maxConnectionsPerIp4)&&(identical(other.maxConnectionsPerIp6Prefix, maxConnectionsPerIp6Prefix) || other.maxConnectionsPerIp6Prefix == maxConnectionsPerIp6Prefix)&&(identical(other.maxConnectionsPerIp6PrefixSize, maxConnectionsPerIp6PrefixSize) || other.maxConnectionsPerIp6PrefixSize == maxConnectionsPerIp6PrefixSize)&&(identical(other.maxConnectionFrequencyPerMin, maxConnectionFrequencyPerMin) || other.maxConnectionFrequencyPerMin == maxConnectionFrequencyPerMin)&&(identical(other.clientAllowlistTimeoutMs, clientAllowlistTimeoutMs) || other.clientAllowlistTimeoutMs == clientAllowlistTimeoutMs)&&(identical(other.reverseConnectionReceiptTimeMs, reverseConnectionReceiptTimeMs) || other.reverseConnectionReceiptTimeMs == reverseConnectionReceiptTimeMs)&&(identical(other.holePunchReceiptTimeMs, holePunchReceiptTimeMs) || other.holePunchReceiptTimeMs == holePunchReceiptTimeMs)&&(identical(other.restrictedNatRetries, restrictedNatRetries) || other.restrictedNatRetries == restrictedNatRetries)&&(identical(other.rpc, rpc) || other.rpc == rpc)&&(identical(other.dht, dht) || other.dht == dht)&&(identical(other.protocol, protocol) || other.protocol == protocol));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidConfigInternalNetwork&&(identical(other.connectionInitialTimeoutMs, connectionInitialTimeoutMs) || other.connectionInitialTimeoutMs == connectionInitialTimeoutMs)&&(identical(other.singleSendTimeoutMs, singleSendTimeoutMs) || other.singleSendTimeoutMs == singleSendTimeoutMs)&&(identical(other.connectionInactivityTimeoutMs, connectionInactivityTimeoutMs) || other.connectionInactivityTimeoutMs == connectionInactivityTimeoutMs)&&(identical(other.maxConnectionsPerIp4, maxConnectionsPerIp4) || other.maxConnectionsPerIp4 == maxConnectionsPerIp4)&&(identical(other.maxConnectionsPerIp6Prefix, maxConnectionsPerIp6Prefix) || other.maxConnectionsPerIp6Prefix == maxConnectionsPerIp6Prefix)&&(identical(other.maxConnectionsPerIp6PrefixSize, maxConnectionsPerIp6PrefixSize) || other.maxConnectionsPerIp6PrefixSize == maxConnectionsPerIp6PrefixSize)&&(identical(other.maxConnectionFrequencyPerMin, maxConnectionFrequencyPerMin) || other.maxConnectionFrequencyPerMin == maxConnectionFrequencyPerMin)&&(identical(other.clientAllowlistTimeoutMs, clientAllowlistTimeoutMs) || other.clientAllowlistTimeoutMs == clientAllowlistTimeoutMs)&&(identical(other.reverseConnectionReceiptTimeMs, reverseConnectionReceiptTimeMs) || other.reverseConnectionReceiptTimeMs == reverseConnectionReceiptTimeMs)&&(identical(other.holePunchReceiptTimeMs, holePunchReceiptTimeMs) || other.holePunchReceiptTimeMs == holePunchReceiptTimeMs)&&(identical(other.restrictedNatRetries, restrictedNatRetries) || other.restrictedNatRetries == restrictedNatRetries)&&(identical(other.rpc, rpc) || other.rpc == rpc)&&(identical(other.dht, dht) || other.dht == dht)&&(identical(other.protocol, protocol) || other.protocol == protocol));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,connectionInitialTimeoutMs,connectionInactivityTimeoutMs,maxConnectionsPerIp4,maxConnectionsPerIp6Prefix,maxConnectionsPerIp6PrefixSize,maxConnectionFrequencyPerMin,clientAllowlistTimeoutMs,reverseConnectionReceiptTimeMs,holePunchReceiptTimeMs,restrictedNatRetries,rpc,dht,protocol);
|
||||
int get hashCode => Object.hash(runtimeType,connectionInitialTimeoutMs,singleSendTimeoutMs,connectionInactivityTimeoutMs,maxConnectionsPerIp4,maxConnectionsPerIp6Prefix,maxConnectionsPerIp6PrefixSize,maxConnectionFrequencyPerMin,clientAllowlistTimeoutMs,reverseConnectionReceiptTimeMs,holePunchReceiptTimeMs,restrictedNatRetries,rpc,dht,protocol);
|
||||
|
||||
@override
|
||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||
return 'VeilidConfigInternalNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, restrictedNatRetries: $restrictedNatRetries, rpc: $rpc, dht: $dht, protocol: $protocol)';
|
||||
return 'VeilidConfigInternalNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, singleSendTimeoutMs: $singleSendTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, restrictedNatRetries: $restrictedNatRetries, rpc: $rpc, dht: $dht, protocol: $protocol)';
|
||||
}
|
||||
|
||||
|
||||
@@ -9158,7 +9158,7 @@ abstract mixin class $VeilidConfigInternalNetworkCopyWith<$Res> {
|
||||
factory $VeilidConfigInternalNetworkCopyWith(VeilidConfigInternalNetwork value, $Res Function(VeilidConfigInternalNetwork) _then) = _$VeilidConfigInternalNetworkCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int connectionInitialTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol
|
||||
int connectionInitialTimeoutMs, int singleSendTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol
|
||||
});
|
||||
|
||||
|
||||
@@ -9175,9 +9175,10 @@ class _$VeilidConfigInternalNetworkCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of VeilidConfigInternalNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? connectionInitialTimeoutMs = null,Object? connectionInactivityTimeoutMs = null,Object? maxConnectionsPerIp4 = null,Object? maxConnectionsPerIp6Prefix = null,Object? maxConnectionsPerIp6PrefixSize = null,Object? maxConnectionFrequencyPerMin = null,Object? clientAllowlistTimeoutMs = null,Object? reverseConnectionReceiptTimeMs = null,Object? holePunchReceiptTimeMs = null,Object? restrictedNatRetries = null,Object? rpc = null,Object? dht = null,Object? protocol = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? connectionInitialTimeoutMs = null,Object? singleSendTimeoutMs = null,Object? connectionInactivityTimeoutMs = null,Object? maxConnectionsPerIp4 = null,Object? maxConnectionsPerIp6Prefix = null,Object? maxConnectionsPerIp6PrefixSize = null,Object? maxConnectionFrequencyPerMin = null,Object? clientAllowlistTimeoutMs = null,Object? reverseConnectionReceiptTimeMs = null,Object? holePunchReceiptTimeMs = null,Object? restrictedNatRetries = null,Object? rpc = null,Object? dht = null,Object? protocol = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
connectionInitialTimeoutMs: null == connectionInitialTimeoutMs ? _self.connectionInitialTimeoutMs : connectionInitialTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,singleSendTimeoutMs: null == singleSendTimeoutMs ? _self.singleSendTimeoutMs : singleSendTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,connectionInactivityTimeoutMs: null == connectionInactivityTimeoutMs ? _self.connectionInactivityTimeoutMs : connectionInactivityTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,maxConnectionsPerIp4: null == maxConnectionsPerIp4 ? _self.maxConnectionsPerIp4 : maxConnectionsPerIp4 // ignore: cast_nullable_to_non_nullable
|
||||
as int,maxConnectionsPerIp6Prefix: null == maxConnectionsPerIp6Prefix ? _self.maxConnectionsPerIp6Prefix : maxConnectionsPerIp6Prefix // ignore: cast_nullable_to_non_nullable
|
||||
@@ -9299,10 +9300,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int connectionInitialTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int connectionInitialTimeoutMs, int singleSendTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _VeilidConfigInternalNetwork() when $default != null:
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);case _:
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.singleSendTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -9320,10 +9321,10 @@ return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeo
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int connectionInitialTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int connectionInitialTimeoutMs, int singleSendTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _VeilidConfigInternalNetwork():
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);}
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.singleSendTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
@@ -9337,10 +9338,10 @@ return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeo
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int connectionInitialTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int connectionInitialTimeoutMs, int singleSendTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _VeilidConfigInternalNetwork() when $default != null:
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);case _:
|
||||
return $default(_that.connectionInitialTimeoutMs,_that.singleSendTimeoutMs,_that.connectionInactivityTimeoutMs,_that.maxConnectionsPerIp4,_that.maxConnectionsPerIp6Prefix,_that.maxConnectionsPerIp6PrefixSize,_that.maxConnectionFrequencyPerMin,_that.clientAllowlistTimeoutMs,_that.reverseConnectionReceiptTimeMs,_that.holePunchReceiptTimeMs,_that.restrictedNatRetries,_that.rpc,_that.dht,_that.protocol);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -9352,10 +9353,11 @@ return $default(_that.connectionInitialTimeoutMs,_that.connectionInactivityTimeo
|
||||
@JsonSerializable()
|
||||
|
||||
class _VeilidConfigInternalNetwork with DiagnosticableTreeMixin implements VeilidConfigInternalNetwork {
|
||||
const _VeilidConfigInternalNetwork({required this.connectionInitialTimeoutMs, required this.connectionInactivityTimeoutMs, required this.maxConnectionsPerIp4, required this.maxConnectionsPerIp6Prefix, required this.maxConnectionsPerIp6PrefixSize, required this.maxConnectionFrequencyPerMin, required this.clientAllowlistTimeoutMs, required this.reverseConnectionReceiptTimeMs, required this.holePunchReceiptTimeMs, required this.restrictedNatRetries, required this.rpc, required this.dht, required this.protocol});
|
||||
const _VeilidConfigInternalNetwork({required this.connectionInitialTimeoutMs, required this.singleSendTimeoutMs, required this.connectionInactivityTimeoutMs, required this.maxConnectionsPerIp4, required this.maxConnectionsPerIp6Prefix, required this.maxConnectionsPerIp6PrefixSize, required this.maxConnectionFrequencyPerMin, required this.clientAllowlistTimeoutMs, required this.reverseConnectionReceiptTimeMs, required this.holePunchReceiptTimeMs, required this.restrictedNatRetries, required this.rpc, required this.dht, required this.protocol});
|
||||
factory _VeilidConfigInternalNetwork.fromJson(Map<String, dynamic> json) => _$VeilidConfigInternalNetworkFromJson(json);
|
||||
|
||||
@override final int connectionInitialTimeoutMs;
|
||||
@override final int singleSendTimeoutMs;
|
||||
@override final int connectionInactivityTimeoutMs;
|
||||
@override final int maxConnectionsPerIp4;
|
||||
@override final int maxConnectionsPerIp6Prefix;
|
||||
@@ -9383,21 +9385,21 @@ Map<String, dynamic> toJson() {
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'VeilidConfigInternalNetwork'))
|
||||
..add(DiagnosticsProperty('connectionInitialTimeoutMs', connectionInitialTimeoutMs))..add(DiagnosticsProperty('connectionInactivityTimeoutMs', connectionInactivityTimeoutMs))..add(DiagnosticsProperty('maxConnectionsPerIp4', maxConnectionsPerIp4))..add(DiagnosticsProperty('maxConnectionsPerIp6Prefix', maxConnectionsPerIp6Prefix))..add(DiagnosticsProperty('maxConnectionsPerIp6PrefixSize', maxConnectionsPerIp6PrefixSize))..add(DiagnosticsProperty('maxConnectionFrequencyPerMin', maxConnectionFrequencyPerMin))..add(DiagnosticsProperty('clientAllowlistTimeoutMs', clientAllowlistTimeoutMs))..add(DiagnosticsProperty('reverseConnectionReceiptTimeMs', reverseConnectionReceiptTimeMs))..add(DiagnosticsProperty('holePunchReceiptTimeMs', holePunchReceiptTimeMs))..add(DiagnosticsProperty('restrictedNatRetries', restrictedNatRetries))..add(DiagnosticsProperty('rpc', rpc))..add(DiagnosticsProperty('dht', dht))..add(DiagnosticsProperty('protocol', protocol));
|
||||
..add(DiagnosticsProperty('connectionInitialTimeoutMs', connectionInitialTimeoutMs))..add(DiagnosticsProperty('singleSendTimeoutMs', singleSendTimeoutMs))..add(DiagnosticsProperty('connectionInactivityTimeoutMs', connectionInactivityTimeoutMs))..add(DiagnosticsProperty('maxConnectionsPerIp4', maxConnectionsPerIp4))..add(DiagnosticsProperty('maxConnectionsPerIp6Prefix', maxConnectionsPerIp6Prefix))..add(DiagnosticsProperty('maxConnectionsPerIp6PrefixSize', maxConnectionsPerIp6PrefixSize))..add(DiagnosticsProperty('maxConnectionFrequencyPerMin', maxConnectionFrequencyPerMin))..add(DiagnosticsProperty('clientAllowlistTimeoutMs', clientAllowlistTimeoutMs))..add(DiagnosticsProperty('reverseConnectionReceiptTimeMs', reverseConnectionReceiptTimeMs))..add(DiagnosticsProperty('holePunchReceiptTimeMs', holePunchReceiptTimeMs))..add(DiagnosticsProperty('restrictedNatRetries', restrictedNatRetries))..add(DiagnosticsProperty('rpc', rpc))..add(DiagnosticsProperty('dht', dht))..add(DiagnosticsProperty('protocol', protocol));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VeilidConfigInternalNetwork&&(identical(other.connectionInitialTimeoutMs, connectionInitialTimeoutMs) || other.connectionInitialTimeoutMs == connectionInitialTimeoutMs)&&(identical(other.connectionInactivityTimeoutMs, connectionInactivityTimeoutMs) || other.connectionInactivityTimeoutMs == connectionInactivityTimeoutMs)&&(identical(other.maxConnectionsPerIp4, maxConnectionsPerIp4) || other.maxConnectionsPerIp4 == maxConnectionsPerIp4)&&(identical(other.maxConnectionsPerIp6Prefix, maxConnectionsPerIp6Prefix) || other.maxConnectionsPerIp6Prefix == maxConnectionsPerIp6Prefix)&&(identical(other.maxConnectionsPerIp6PrefixSize, maxConnectionsPerIp6PrefixSize) || other.maxConnectionsPerIp6PrefixSize == maxConnectionsPerIp6PrefixSize)&&(identical(other.maxConnectionFrequencyPerMin, maxConnectionFrequencyPerMin) || other.maxConnectionFrequencyPerMin == maxConnectionFrequencyPerMin)&&(identical(other.clientAllowlistTimeoutMs, clientAllowlistTimeoutMs) || other.clientAllowlistTimeoutMs == clientAllowlistTimeoutMs)&&(identical(other.reverseConnectionReceiptTimeMs, reverseConnectionReceiptTimeMs) || other.reverseConnectionReceiptTimeMs == reverseConnectionReceiptTimeMs)&&(identical(other.holePunchReceiptTimeMs, holePunchReceiptTimeMs) || other.holePunchReceiptTimeMs == holePunchReceiptTimeMs)&&(identical(other.restrictedNatRetries, restrictedNatRetries) || other.restrictedNatRetries == restrictedNatRetries)&&(identical(other.rpc, rpc) || other.rpc == rpc)&&(identical(other.dht, dht) || other.dht == dht)&&(identical(other.protocol, protocol) || other.protocol == protocol));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VeilidConfigInternalNetwork&&(identical(other.connectionInitialTimeoutMs, connectionInitialTimeoutMs) || other.connectionInitialTimeoutMs == connectionInitialTimeoutMs)&&(identical(other.singleSendTimeoutMs, singleSendTimeoutMs) || other.singleSendTimeoutMs == singleSendTimeoutMs)&&(identical(other.connectionInactivityTimeoutMs, connectionInactivityTimeoutMs) || other.connectionInactivityTimeoutMs == connectionInactivityTimeoutMs)&&(identical(other.maxConnectionsPerIp4, maxConnectionsPerIp4) || other.maxConnectionsPerIp4 == maxConnectionsPerIp4)&&(identical(other.maxConnectionsPerIp6Prefix, maxConnectionsPerIp6Prefix) || other.maxConnectionsPerIp6Prefix == maxConnectionsPerIp6Prefix)&&(identical(other.maxConnectionsPerIp6PrefixSize, maxConnectionsPerIp6PrefixSize) || other.maxConnectionsPerIp6PrefixSize == maxConnectionsPerIp6PrefixSize)&&(identical(other.maxConnectionFrequencyPerMin, maxConnectionFrequencyPerMin) || other.maxConnectionFrequencyPerMin == maxConnectionFrequencyPerMin)&&(identical(other.clientAllowlistTimeoutMs, clientAllowlistTimeoutMs) || other.clientAllowlistTimeoutMs == clientAllowlistTimeoutMs)&&(identical(other.reverseConnectionReceiptTimeMs, reverseConnectionReceiptTimeMs) || other.reverseConnectionReceiptTimeMs == reverseConnectionReceiptTimeMs)&&(identical(other.holePunchReceiptTimeMs, holePunchReceiptTimeMs) || other.holePunchReceiptTimeMs == holePunchReceiptTimeMs)&&(identical(other.restrictedNatRetries, restrictedNatRetries) || other.restrictedNatRetries == restrictedNatRetries)&&(identical(other.rpc, rpc) || other.rpc == rpc)&&(identical(other.dht, dht) || other.dht == dht)&&(identical(other.protocol, protocol) || other.protocol == protocol));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,connectionInitialTimeoutMs,connectionInactivityTimeoutMs,maxConnectionsPerIp4,maxConnectionsPerIp6Prefix,maxConnectionsPerIp6PrefixSize,maxConnectionFrequencyPerMin,clientAllowlistTimeoutMs,reverseConnectionReceiptTimeMs,holePunchReceiptTimeMs,restrictedNatRetries,rpc,dht,protocol);
|
||||
int get hashCode => Object.hash(runtimeType,connectionInitialTimeoutMs,singleSendTimeoutMs,connectionInactivityTimeoutMs,maxConnectionsPerIp4,maxConnectionsPerIp6Prefix,maxConnectionsPerIp6PrefixSize,maxConnectionFrequencyPerMin,clientAllowlistTimeoutMs,reverseConnectionReceiptTimeMs,holePunchReceiptTimeMs,restrictedNatRetries,rpc,dht,protocol);
|
||||
|
||||
@override
|
||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||
return 'VeilidConfigInternalNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, restrictedNatRetries: $restrictedNatRetries, rpc: $rpc, dht: $dht, protocol: $protocol)';
|
||||
return 'VeilidConfigInternalNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, singleSendTimeoutMs: $singleSendTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, restrictedNatRetries: $restrictedNatRetries, rpc: $rpc, dht: $dht, protocol: $protocol)';
|
||||
}
|
||||
|
||||
|
||||
@@ -9408,7 +9410,7 @@ abstract mixin class _$VeilidConfigInternalNetworkCopyWith<$Res> implements $Vei
|
||||
factory _$VeilidConfigInternalNetworkCopyWith(_VeilidConfigInternalNetwork value, $Res Function(_VeilidConfigInternalNetwork) _then) = __$VeilidConfigInternalNetworkCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int connectionInitialTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol
|
||||
int connectionInitialTimeoutMs, int singleSendTimeoutMs, int connectionInactivityTimeoutMs, int maxConnectionsPerIp4, int maxConnectionsPerIp6Prefix, int maxConnectionsPerIp6PrefixSize, int maxConnectionFrequencyPerMin, int clientAllowlistTimeoutMs, int reverseConnectionReceiptTimeMs, int holePunchReceiptTimeMs, int restrictedNatRetries, VeilidConfigInternalRPC rpc, VeilidConfigInternalDHT dht, VeilidConfigInternalProtocol protocol
|
||||
});
|
||||
|
||||
|
||||
@@ -9425,9 +9427,10 @@ class __$VeilidConfigInternalNetworkCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of VeilidConfigInternalNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? connectionInitialTimeoutMs = null,Object? connectionInactivityTimeoutMs = null,Object? maxConnectionsPerIp4 = null,Object? maxConnectionsPerIp6Prefix = null,Object? maxConnectionsPerIp6PrefixSize = null,Object? maxConnectionFrequencyPerMin = null,Object? clientAllowlistTimeoutMs = null,Object? reverseConnectionReceiptTimeMs = null,Object? holePunchReceiptTimeMs = null,Object? restrictedNatRetries = null,Object? rpc = null,Object? dht = null,Object? protocol = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? connectionInitialTimeoutMs = null,Object? singleSendTimeoutMs = null,Object? connectionInactivityTimeoutMs = null,Object? maxConnectionsPerIp4 = null,Object? maxConnectionsPerIp6Prefix = null,Object? maxConnectionsPerIp6PrefixSize = null,Object? maxConnectionFrequencyPerMin = null,Object? clientAllowlistTimeoutMs = null,Object? reverseConnectionReceiptTimeMs = null,Object? holePunchReceiptTimeMs = null,Object? restrictedNatRetries = null,Object? rpc = null,Object? dht = null,Object? protocol = null,}) {
|
||||
return _then(_VeilidConfigInternalNetwork(
|
||||
connectionInitialTimeoutMs: null == connectionInitialTimeoutMs ? _self.connectionInitialTimeoutMs : connectionInitialTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,singleSendTimeoutMs: null == singleSendTimeoutMs ? _self.singleSendTimeoutMs : singleSendTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,connectionInactivityTimeoutMs: null == connectionInactivityTimeoutMs ? _self.connectionInactivityTimeoutMs : connectionInactivityTimeoutMs // ignore: cast_nullable_to_non_nullable
|
||||
as int,maxConnectionsPerIp4: null == maxConnectionsPerIp4 ? _self.maxConnectionsPerIp4 : maxConnectionsPerIp4 // ignore: cast_nullable_to_non_nullable
|
||||
as int,maxConnectionsPerIp6Prefix: null == maxConnectionsPerIp6Prefix ? _self.maxConnectionsPerIp6Prefix : maxConnectionsPerIp6Prefix // ignore: cast_nullable_to_non_nullable
|
||||
|
||||
@@ -637,6 +637,7 @@ _VeilidConfigInternalNetwork _$VeilidConfigInternalNetworkFromJson(
|
||||
) => _VeilidConfigInternalNetwork(
|
||||
connectionInitialTimeoutMs: (json['connectionInitialTimeoutMs'] as num)
|
||||
.toInt(),
|
||||
singleSendTimeoutMs: (json['singleSendTimeoutMs'] as num).toInt(),
|
||||
connectionInactivityTimeoutMs: (json['connectionInactivityTimeoutMs'] as num)
|
||||
.toInt(),
|
||||
maxConnectionsPerIp4: (json['maxConnectionsPerIp4'] as num).toInt(),
|
||||
@@ -660,6 +661,7 @@ Map<String, dynamic> _$VeilidConfigInternalNetworkToJson(
|
||||
_VeilidConfigInternalNetwork instance,
|
||||
) => <String, dynamic>{
|
||||
'connectionInitialTimeoutMs': instance.connectionInitialTimeoutMs,
|
||||
'singleSendTimeoutMs': instance.singleSendTimeoutMs,
|
||||
'connectionInactivityTimeoutMs': instance.connectionInactivityTimeoutMs,
|
||||
'maxConnectionsPerIp4': instance.maxConnectionsPerIp4,
|
||||
'maxConnectionsPerIp6Prefix': instance.maxConnectionsPerIp6Prefix,
|
||||
|
||||
@@ -16,15 +16,17 @@ part 'veilid_dht_transaction.g.dart';
|
||||
sealed class DHTTransactionSetValueOptions
|
||||
with _$DHTTransactionSetValueOptions {
|
||||
/// Builds set options, optionally overriding the record's default [writer].
|
||||
const factory DHTTransactionSetValueOptions({KeyPair? writer}) =
|
||||
_DHTTransactionSetValueOptions;
|
||||
/// `minSeqnum` raises the sequence number to at least that value after the
|
||||
/// automatic increment; [ValueData.maxSeqnum] minus n leaves n writes after
|
||||
/// this one.
|
||||
const factory DHTTransactionSetValueOptions({
|
||||
KeyPair? writer,
|
||||
int? minSeqnum,
|
||||
}) = _DHTTransactionSetValueOptions;
|
||||
|
||||
/// Decodes options from JSON.
|
||||
factory DHTTransactionSetValueOptions.fromJson(dynamic json) =>
|
||||
_$DHTTransactionSetValueOptionsFromJson(json as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {'writer': writer};
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DHTTransactionSetValueOptions {
|
||||
|
||||
KeyPair? get writer;
|
||||
KeyPair? get writer; int? get minSeqnum;
|
||||
/// Create a copy of DHTTransactionSetValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -28,16 +28,16 @@ $DHTTransactionSetValueOptionsCopyWith<DHTTransactionSetValueOptions> get copyWi
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DHTTransactionSetValueOptions&&(identical(other.writer, writer) || other.writer == writer));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DHTTransactionSetValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.minSeqnum, minSeqnum) || other.minSeqnum == minSeqnum));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,writer);
|
||||
int get hashCode => Object.hash(runtimeType,writer,minSeqnum);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DHTTransactionSetValueOptions(writer: $writer)';
|
||||
return 'DHTTransactionSetValueOptions(writer: $writer, minSeqnum: $minSeqnum)';
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract mixin class $DHTTransactionSetValueOptionsCopyWith<$Res> {
|
||||
factory $DHTTransactionSetValueOptionsCopyWith(DHTTransactionSetValueOptions value, $Res Function(DHTTransactionSetValueOptions) _then) = _$DHTTransactionSetValueOptionsCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
KeyPair? writer
|
||||
KeyPair? writer, int? minSeqnum
|
||||
});
|
||||
|
||||
|
||||
@@ -65,10 +65,11 @@ class _$DHTTransactionSetValueOptionsCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of DHTTransactionSetValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? writer = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? writer = freezed,Object? minSeqnum = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
writer: freezed == writer ? _self.writer : writer // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair?,
|
||||
as KeyPair?,minSeqnum: freezed == minSeqnum ? _self.minSeqnum : minSeqnum // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -150,10 +151,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( KeyPair? writer)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( KeyPair? writer, int? minSeqnum)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DHTTransactionSetValueOptions() when $default != null:
|
||||
return $default(_that.writer);case _:
|
||||
return $default(_that.writer,_that.minSeqnum);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -171,10 +172,10 @@ return $default(_that.writer);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( KeyPair? writer) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( KeyPair? writer, int? minSeqnum) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DHTTransactionSetValueOptions():
|
||||
return $default(_that.writer);}
|
||||
return $default(_that.writer,_that.minSeqnum);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
@@ -188,10 +189,10 @@ return $default(_that.writer);}
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( KeyPair? writer)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( KeyPair? writer, int? minSeqnum)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DHTTransactionSetValueOptions() when $default != null:
|
||||
return $default(_that.writer);case _:
|
||||
return $default(_that.writer,_that.minSeqnum);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -203,10 +204,11 @@ return $default(_that.writer);case _:
|
||||
@JsonSerializable()
|
||||
|
||||
class _DHTTransactionSetValueOptions implements DHTTransactionSetValueOptions {
|
||||
const _DHTTransactionSetValueOptions({this.writer});
|
||||
const _DHTTransactionSetValueOptions({this.writer, this.minSeqnum});
|
||||
factory _DHTTransactionSetValueOptions.fromJson(Map<String, dynamic> json) => _$DHTTransactionSetValueOptionsFromJson(json);
|
||||
|
||||
@override final KeyPair? writer;
|
||||
@override final int? minSeqnum;
|
||||
|
||||
/// Create a copy of DHTTransactionSetValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -221,16 +223,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DHTTransactionSetValueOptions&&(identical(other.writer, writer) || other.writer == writer));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DHTTransactionSetValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.minSeqnum, minSeqnum) || other.minSeqnum == minSeqnum));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,writer);
|
||||
int get hashCode => Object.hash(runtimeType,writer,minSeqnum);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DHTTransactionSetValueOptions(writer: $writer)';
|
||||
return 'DHTTransactionSetValueOptions(writer: $writer, minSeqnum: $minSeqnum)';
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +243,7 @@ abstract mixin class _$DHTTransactionSetValueOptionsCopyWith<$Res> implements $D
|
||||
factory _$DHTTransactionSetValueOptionsCopyWith(_DHTTransactionSetValueOptions value, $Res Function(_DHTTransactionSetValueOptions) _then) = __$DHTTransactionSetValueOptionsCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
KeyPair? writer
|
||||
KeyPair? writer, int? minSeqnum
|
||||
});
|
||||
|
||||
|
||||
@@ -258,10 +260,11 @@ class __$DHTTransactionSetValueOptionsCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of DHTTransactionSetValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? writer = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? writer = freezed,Object? minSeqnum = freezed,}) {
|
||||
return _then(_DHTTransactionSetValueOptions(
|
||||
writer: freezed == writer ? _self.writer : writer // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair?,
|
||||
as KeyPair?,minSeqnum: freezed == minSeqnum ? _self.minSeqnum : minSeqnum // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,12 @@ _DHTTransactionSetValueOptions _$DHTTransactionSetValueOptionsFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DHTTransactionSetValueOptions(
|
||||
writer: json['writer'] == null ? null : KeyPair.fromJson(json['writer']),
|
||||
minSeqnum: (json['minSeqnum'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DHTTransactionSetValueOptionsToJson(
|
||||
_DHTTransactionSetValueOptions instance,
|
||||
) => <String, dynamic>{'writer': instance.writer?.toJson()};
|
||||
) => <String, dynamic>{
|
||||
'writer': instance.writer?.toJson(),
|
||||
'minSeqnum': instance.minSeqnum,
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// Low-level platform binding to veilid-core; not part of the documented public API.
|
||||
// The asset id below must match `assetName` in hook/build.dart.
|
||||
// @DefaultAsset below names the asset hook/build.dart declares as `assetName`.
|
||||
@DefaultAsset('package:veilid/veilid_ffi.dart')
|
||||
library;
|
||||
|
||||
@@ -20,7 +20,7 @@ import 'veilid.dart';
|
||||
typedef _DartPostCObject =
|
||||
NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>;
|
||||
|
||||
// fn veilid_version() -> VeilidVersion
|
||||
// Return layout of veilid_version()
|
||||
final class VeilidVersionFFI extends Struct {
|
||||
@Uint32()
|
||||
external int major;
|
||||
@@ -1591,7 +1591,7 @@ class VeilidFFI extends Veilid {
|
||||
)
|
||||
external static int _changeLogLevel(
|
||||
Pointer<Utf8> layer,
|
||||
Pointer<Utf8> logLevel,
|
||||
Pointer<Utf8> directives,
|
||||
);
|
||||
|
||||
@Native<Void Function(Pointer<Utf8>, Pointer<Utf8>)>(
|
||||
@@ -1642,7 +1642,7 @@ class VeilidFFI extends Veilid {
|
||||
)
|
||||
external static int _routingContextWithSafety(
|
||||
int id,
|
||||
Pointer<Utf8> stability,
|
||||
Pointer<Utf8> safetySelection,
|
||||
);
|
||||
|
||||
@Native<Uint32 Function(Uint32, Pointer<Utf8>)>(
|
||||
@@ -1673,7 +1673,7 @@ class VeilidFFI extends Veilid {
|
||||
int port,
|
||||
int id,
|
||||
Pointer<Utf8> target,
|
||||
Pointer<Utf8> request,
|
||||
Pointer<Utf8> message,
|
||||
);
|
||||
|
||||
@Native<Void Function(Int64, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>)>(
|
||||
@@ -1742,7 +1742,7 @@ class VeilidFFI extends Veilid {
|
||||
Pointer<Utf8> key,
|
||||
int subkey,
|
||||
Pointer<Utf8> data,
|
||||
Pointer<Utf8> writer,
|
||||
Pointer<Utf8> options,
|
||||
);
|
||||
|
||||
@Native<
|
||||
@@ -1806,8 +1806,8 @@ class VeilidFFI extends Veilid {
|
||||
)
|
||||
external static void _transactDHTRecords(
|
||||
int port,
|
||||
Pointer<Utf8> records,
|
||||
Pointer<Utf8> defaultSigningKey,
|
||||
Pointer<Utf8> recordKeys,
|
||||
Pointer<Utf8> options,
|
||||
);
|
||||
|
||||
@Native<Void Function(Int64)>(symbol: 'new_private_route')
|
||||
@@ -1827,14 +1827,14 @@ class VeilidFFI extends Veilid {
|
||||
external static void _importRemotePrivateRoute(int port, Pointer<Utf8> blob);
|
||||
|
||||
@Native<Void Function(Int64, Pointer<Utf8>)>(symbol: 'release_private_route')
|
||||
external static void _releasePrivateRoute(int port, Pointer<Utf8> key);
|
||||
external static void _releasePrivateRoute(int port, Pointer<Utf8> routeId);
|
||||
|
||||
@Native<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>)>(
|
||||
symbol: 'app_call_reply',
|
||||
)
|
||||
external static void _appCallReply(
|
||||
int port,
|
||||
Pointer<Utf8> id,
|
||||
Pointer<Utf8> callId,
|
||||
Pointer<Utf8> message,
|
||||
);
|
||||
|
||||
@@ -2319,7 +2319,7 @@ class VeilidFFI extends Veilid {
|
||||
external static int _nowIncreasing();
|
||||
|
||||
@Native<Void Function(Int64, Pointer<Utf8>)>(symbol: 'debug')
|
||||
external static void _debug(int port, Pointer<Utf8> logLevel);
|
||||
external static void _debug(int port, Pointer<Utf8> command);
|
||||
|
||||
@Native<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>)>(
|
||||
symbol: 'save_user_secret',
|
||||
|
||||
@@ -451,26 +451,24 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
|
||||
EncapsulationKey recipient,
|
||||
Uint8List aad,
|
||||
Uint8List plaintext,
|
||||
) =>
|
||||
_wasmPromiseUint8List('crypto_hpke_seal', [
|
||||
_kind.toJS,
|
||||
jsonEncode(recipient).toJS,
|
||||
base64UrlNoPadEncode(aad).toJS,
|
||||
base64UrlNoPadEncode(plaintext).toJS,
|
||||
]);
|
||||
) => _wasmPromiseUint8List('crypto_hpke_seal', [
|
||||
_kind.toJS,
|
||||
jsonEncode(recipient).toJS,
|
||||
base64UrlNoPadEncode(aad).toJS,
|
||||
base64UrlNoPadEncode(plaintext).toJS,
|
||||
]);
|
||||
|
||||
@override
|
||||
Future<Uint8List> hpkeOpen(
|
||||
DecapsulationKey secret,
|
||||
Uint8List aad,
|
||||
Uint8List sealed,
|
||||
) =>
|
||||
_wasmPromiseUint8List('crypto_hpke_open', [
|
||||
_kind.toJS,
|
||||
jsonEncode(secret).toJS,
|
||||
base64UrlNoPadEncode(aad).toJS,
|
||||
base64UrlNoPadEncode(sealed).toJS,
|
||||
]);
|
||||
) => _wasmPromiseUint8List('crypto_hpke_open', [
|
||||
_kind.toJS,
|
||||
jsonEncode(secret).toJS,
|
||||
base64UrlNoPadEncode(aad).toJS,
|
||||
base64UrlNoPadEncode(sealed).toJS,
|
||||
]);
|
||||
|
||||
@override
|
||||
Future<Uint8List> randomBytes(int len) =>
|
||||
@@ -603,21 +601,20 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
|
||||
|
||||
@override
|
||||
Future<EncapsulationKey> encapsulationKeyFromSigningKey(PublicKey key) =>
|
||||
_wasmPromiseJson('crypto_encapsulation_key_from_signing_key',
|
||||
EncapsulationKey.fromJson, [
|
||||
_kind.toJS,
|
||||
jsonEncode(key).toJS,
|
||||
]);
|
||||
_wasmPromiseJson(
|
||||
'crypto_encapsulation_key_from_signing_key',
|
||||
EncapsulationKey.fromJson,
|
||||
[_kind.toJS, jsonEncode(key).toJS],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<DecapsulationKey> decapsulationKeyFromSigningSecret(
|
||||
SecretKey secret,
|
||||
) =>
|
||||
_wasmPromiseJson('crypto_decapsulation_key_from_signing_secret',
|
||||
DecapsulationKey.fromJson, [
|
||||
_kind.toJS,
|
||||
jsonEncode(secret).toJS,
|
||||
]);
|
||||
) => _wasmPromiseJson(
|
||||
'crypto_decapsulation_key_from_signing_secret',
|
||||
DecapsulationKey.fromJson,
|
||||
[_kind.toJS, jsonEncode(secret).toJS],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<HashDigest> generateHash(Uint8List data) => _wasmPromiseJson(
|
||||
@@ -1253,4 +1250,4 @@ class VeilidJS extends Veilid {
|
||||
|
||||
@override
|
||||
String defaultVeilidConfig() => _wasmCallString('default_veilid_config', []);
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,4 @@ class VeilidPluginStubWeb {
|
||||
details: "Veilid for Web doesn't implement '${call.method}'",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,4 @@ Veilid getVeilid() => throw UnsupportedError('Cannot create Veilid object');
|
||||
Uint8List convertUint8ListFromJson(dynamic json) =>
|
||||
throw UnsupportedError('Cannot convertUint8ListFromJson');
|
||||
dynamic convertUint8ListToJson(Uint8List data) =>
|
||||
throw UnsupportedError('Cannot convertUint8ListToJson');
|
||||
throw UnsupportedError('Cannot convertUint8ListToJson');
|
||||
@@ -226,6 +226,9 @@ sealed class ValueData with _$ValueData {
|
||||
/// Maximum length in bytes of the data a single subkey may hold.
|
||||
static const maxLen = 32768;
|
||||
|
||||
/// The largest sequence number. Subtract n for a `minSeqnum` leaving n writes.
|
||||
static const maxSeqnum = 0xFFFFFFFE;
|
||||
|
||||
/// `seq` time-orders changes to the subkey; `writer` is the public identity
|
||||
/// key of the writer. In debug builds, throws [AssertionError] if `seq` is
|
||||
/// outside `0..=4294967295` or `data` exceeds [maxLen] bytes.
|
||||
@@ -517,19 +520,18 @@ enum DHTReportScope {
|
||||
sealed class SetDHTValueOptions with _$SetDHTValueOptions {
|
||||
/// `writer` overrides the writer key pair for the operation. `allowOffline`
|
||||
/// defaults to true; when false, an offline node returns a TryAgain error
|
||||
/// instead of writing.
|
||||
const factory SetDHTValueOptions({KeyPair? writer, bool? allowOffline}) =
|
||||
_SetDHTValueOptions;
|
||||
/// instead of writing. `minSeqnum` raises the sequence number to at least
|
||||
/// that value after the automatic increment; [ValueData.maxSeqnum] minus n
|
||||
/// leaves n writes after this one.
|
||||
const factory SetDHTValueOptions({
|
||||
KeyPair? writer,
|
||||
bool? allowOffline,
|
||||
int? minSeqnum,
|
||||
}) = _SetDHTValueOptions;
|
||||
|
||||
/// Decode a [SetDHTValueOptions] from its JSON representation.
|
||||
factory SetDHTValueOptions.fromJson(dynamic json) =>
|
||||
_$SetDHTValueOptionsFromJson(json as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() => {
|
||||
'writer': writer,
|
||||
'allow_offline': allowOffline,
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
@@ -2281,7 +2281,7 @@ as List<int?>,
|
||||
/// @nodoc
|
||||
mixin _$SetDHTValueOptions {
|
||||
|
||||
KeyPair? get writer; bool? get allowOffline;
|
||||
KeyPair? get writer; bool? get allowOffline; int? get minSeqnum;
|
||||
/// Create a copy of SetDHTValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -2294,16 +2294,16 @@ $SetDHTValueOptionsCopyWith<SetDHTValueOptions> get copyWith => _$SetDHTValueOpt
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SetDHTValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.allowOffline, allowOffline) || other.allowOffline == allowOffline));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SetDHTValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.allowOffline, allowOffline) || other.allowOffline == allowOffline)&&(identical(other.minSeqnum, minSeqnum) || other.minSeqnum == minSeqnum));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,writer,allowOffline);
|
||||
int get hashCode => Object.hash(runtimeType,writer,allowOffline,minSeqnum);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline)';
|
||||
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline, minSeqnum: $minSeqnum)';
|
||||
}
|
||||
|
||||
|
||||
@@ -2314,7 +2314,7 @@ abstract mixin class $SetDHTValueOptionsCopyWith<$Res> {
|
||||
factory $SetDHTValueOptionsCopyWith(SetDHTValueOptions value, $Res Function(SetDHTValueOptions) _then) = _$SetDHTValueOptionsCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
KeyPair? writer, bool? allowOffline
|
||||
KeyPair? writer, bool? allowOffline, int? minSeqnum
|
||||
});
|
||||
|
||||
|
||||
@@ -2331,11 +2331,12 @@ class _$SetDHTValueOptionsCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SetDHTValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? writer = freezed,Object? allowOffline = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? writer = freezed,Object? allowOffline = freezed,Object? minSeqnum = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
writer: freezed == writer ? _self.writer : writer // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair?,allowOffline: freezed == allowOffline ? _self.allowOffline : allowOffline // ignore: cast_nullable_to_non_nullable
|
||||
as bool?,
|
||||
as bool?,minSeqnum: freezed == minSeqnum ? _self.minSeqnum : minSeqnum // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2417,10 +2418,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( KeyPair? writer, bool? allowOffline)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( KeyPair? writer, bool? allowOffline, int? minSeqnum)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SetDHTValueOptions() when $default != null:
|
||||
return $default(_that.writer,_that.allowOffline);case _:
|
||||
return $default(_that.writer,_that.allowOffline,_that.minSeqnum);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -2438,10 +2439,10 @@ return $default(_that.writer,_that.allowOffline);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( KeyPair? writer, bool? allowOffline) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( KeyPair? writer, bool? allowOffline, int? minSeqnum) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SetDHTValueOptions():
|
||||
return $default(_that.writer,_that.allowOffline);}
|
||||
return $default(_that.writer,_that.allowOffline,_that.minSeqnum);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
@@ -2455,10 +2456,10 @@ return $default(_that.writer,_that.allowOffline);}
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( KeyPair? writer, bool? allowOffline)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( KeyPair? writer, bool? allowOffline, int? minSeqnum)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SetDHTValueOptions() when $default != null:
|
||||
return $default(_that.writer,_that.allowOffline);case _:
|
||||
return $default(_that.writer,_that.allowOffline,_that.minSeqnum);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -2470,11 +2471,12 @@ return $default(_that.writer,_that.allowOffline);case _:
|
||||
@JsonSerializable()
|
||||
|
||||
class _SetDHTValueOptions implements SetDHTValueOptions {
|
||||
const _SetDHTValueOptions({this.writer, this.allowOffline});
|
||||
const _SetDHTValueOptions({this.writer, this.allowOffline, this.minSeqnum});
|
||||
factory _SetDHTValueOptions.fromJson(Map<String, dynamic> json) => _$SetDHTValueOptionsFromJson(json);
|
||||
|
||||
@override final KeyPair? writer;
|
||||
@override final bool? allowOffline;
|
||||
@override final int? minSeqnum;
|
||||
|
||||
/// Create a copy of SetDHTValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -2489,16 +2491,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SetDHTValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.allowOffline, allowOffline) || other.allowOffline == allowOffline));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SetDHTValueOptions&&(identical(other.writer, writer) || other.writer == writer)&&(identical(other.allowOffline, allowOffline) || other.allowOffline == allowOffline)&&(identical(other.minSeqnum, minSeqnum) || other.minSeqnum == minSeqnum));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,writer,allowOffline);
|
||||
int get hashCode => Object.hash(runtimeType,writer,allowOffline,minSeqnum);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline)';
|
||||
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline, minSeqnum: $minSeqnum)';
|
||||
}
|
||||
|
||||
|
||||
@@ -2509,7 +2511,7 @@ abstract mixin class _$SetDHTValueOptionsCopyWith<$Res> implements $SetDHTValueO
|
||||
factory _$SetDHTValueOptionsCopyWith(_SetDHTValueOptions value, $Res Function(_SetDHTValueOptions) _then) = __$SetDHTValueOptionsCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
KeyPair? writer, bool? allowOffline
|
||||
KeyPair? writer, bool? allowOffline, int? minSeqnum
|
||||
});
|
||||
|
||||
|
||||
@@ -2526,11 +2528,12 @@ class __$SetDHTValueOptionsCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SetDHTValueOptions
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? writer = freezed,Object? allowOffline = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? writer = freezed,Object? allowOffline = freezed,Object? minSeqnum = freezed,}) {
|
||||
return _then(_SetDHTValueOptions(
|
||||
writer: freezed == writer ? _self.writer : writer // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair?,allowOffline: freezed == allowOffline ? _self.allowOffline : allowOffline // ignore: cast_nullable_to_non_nullable
|
||||
as bool?,
|
||||
as bool?,minSeqnum: freezed == minSeqnum ? _self.minSeqnum : minSeqnum // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -153,12 +153,14 @@ _SetDHTValueOptions _$SetDHTValueOptionsFromJson(Map<String, dynamic> json) =>
|
||||
_SetDHTValueOptions(
|
||||
writer: json['writer'] == null ? null : KeyPair.fromJson(json['writer']),
|
||||
allowOffline: json['allowOffline'] as bool?,
|
||||
minSeqnum: (json['minSeqnum'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SetDHTValueOptionsToJson(_SetDHTValueOptions instance) =>
|
||||
<String, dynamic>{
|
||||
'writer': instance.writer?.toJson(),
|
||||
'allowOffline': instance.allowOffline,
|
||||
'minSeqnum': instance.minSeqnum,
|
||||
};
|
||||
|
||||
_TransactDHTRecordsOptions _$TransactDHTRecordsOptionsFromJson(
|
||||
|
||||
@@ -162,8 +162,9 @@ void runWithIntegrationLog(void Function() body) {
|
||||
}
|
||||
|
||||
/// Two-pane debug app for integration tests: scrollable xterm log on top,
|
||||
/// test-status pane on the bottom. Call `runApp(const IntegrationLogApp())`
|
||||
/// right after `IntegrationTestWidgetsFlutterBinding.ensureInitialized()`.
|
||||
/// test-status pane on the bottom, separated by a drag-resizable divider.
|
||||
/// Call `runApp(const IntegrationLogApp())` right after
|
||||
/// `IntegrationTestWidgetsFlutterBinding.ensureInitialized()`.
|
||||
class IntegrationLogApp extends StatefulWidget {
|
||||
const IntegrationLogApp({super.key});
|
||||
|
||||
@@ -172,8 +173,13 @@ class IntegrationLogApp extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _IntegrationLogAppState extends State<IntegrationLogApp> {
|
||||
static const _statusPaneMinHeight = 48.0;
|
||||
static const _logPaneMinHeight = 64.0;
|
||||
static const _dividerHeight = 5.0;
|
||||
|
||||
final _terminalController = TerminalController();
|
||||
final _scrollController = ScrollController();
|
||||
double _statusPaneHeight = 180;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -212,37 +218,84 @@ class _IntegrationLogAppState extends State<IntegrationLogApp> {
|
||||
await Clipboard.setData(ClipboardData(text: text));
|
||||
}
|
||||
|
||||
Widget _divider(double maxStatusHeight) => MouseRegion(
|
||||
cursor: SystemMouseCursors.resizeRow,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onVerticalDragUpdate: (details) => setState(() {
|
||||
_statusPaneHeight = (_statusPaneHeight - details.delta.dy).clamp(
|
||||
_statusPaneMinHeight,
|
||||
maxStatusHeight,
|
||||
);
|
||||
}),
|
||||
child: Container(
|
||||
height: _dividerHeight,
|
||||
color: Colors.grey.shade600,
|
||||
alignment: Alignment.center,
|
||||
child: Container(width: 64, height: 2, color: Colors.grey.shade900),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData.dark(),
|
||||
home: Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Scrollbar(
|
||||
controller: _scrollController,
|
||||
thumbVisibility: true,
|
||||
child: TerminalView(
|
||||
IntegrationLogSink.instance.terminal,
|
||||
controller: _terminalController,
|
||||
scrollController: _scrollController,
|
||||
autofocus: true,
|
||||
textStyle: const TerminalStyle(fontSize: 10),
|
||||
body: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final maxStatusHeight =
|
||||
(constraints.maxHeight - _dividerHeight - _logPaneMinHeight)
|
||||
.clamp(_statusPaneMinHeight, double.infinity);
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Scrollbar(
|
||||
controller: _scrollController,
|
||||
thumbVisibility: true,
|
||||
child: TerminalView(
|
||||
IntegrationLogSink.instance.terminal,
|
||||
controller: _terminalController,
|
||||
scrollController: _scrollController,
|
||||
autofocus: true,
|
||||
textStyle: const TerminalStyle(fontSize: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(height: 1, color: Colors.grey.shade800),
|
||||
const SizedBox(height: 180, child: IntegrationTestStatusPane()),
|
||||
],
|
||||
_divider(maxStatusHeight),
|
||||
SizedBox(
|
||||
// clamp at render so a resize keeps the dragged height
|
||||
height: _statusPaneHeight.clamp(
|
||||
_statusPaneMinHeight,
|
||||
maxStatusHeight,
|
||||
),
|
||||
child: const IntegrationTestStatusPane(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class IntegrationTestStatusPane extends StatelessWidget {
|
||||
class IntegrationTestStatusPane extends StatefulWidget {
|
||||
const IntegrationTestStatusPane({super.key});
|
||||
|
||||
@override
|
||||
State<IntegrationTestStatusPane> createState() =>
|
||||
_IntegrationTestStatusPaneState();
|
||||
}
|
||||
|
||||
class _IntegrationTestStatusPaneState extends State<IntegrationTestStatusPane> {
|
||||
final _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AnimatedBuilder(
|
||||
animation: IntegrationTestStatusSink.instance,
|
||||
@@ -294,30 +347,36 @@ class IntegrationTestStatusPane extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
reverse: true,
|
||||
itemCount: sink.results.length,
|
||||
itemBuilder: (context, i) {
|
||||
final r = sink.results[sink.results.length - 1 - i];
|
||||
final icon = r.status == TestStatus.passed ? '✓' : '✗';
|
||||
final color = r.status == TestStatus.passed
|
||||
? Colors.greenAccent
|
||||
: Colors.redAccent;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 1,
|
||||
),
|
||||
child: Text(
|
||||
'$icon ${r.name} (${r.elapsedMs}ms)',
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 11,
|
||||
fontFamily: 'monospace',
|
||||
child: Scrollbar(
|
||||
controller: _scrollController,
|
||||
thumbVisibility: true,
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
reverse: true,
|
||||
primary: false,
|
||||
itemCount: sink.results.length,
|
||||
itemBuilder: (context, i) {
|
||||
final r = sink.results[sink.results.length - 1 - i];
|
||||
final icon = r.status == TestStatus.passed ? '✓' : '✗';
|
||||
final color = r.status == TestStatus.passed
|
||||
? Colors.greenAccent
|
||||
: Colors.redAccent;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'$icon ${r.name} (${r.elapsedMs}ms)',
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 11,
|
||||
fontFamily: 'monospace',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -33,8 +33,7 @@ class LogFixture {
|
||||
}
|
||||
|
||||
void _log(VeilidConfigLogLevel level, String message) {
|
||||
final line =
|
||||
'${_timestamp()} ${level.name.toUpperCase()} [test] $message';
|
||||
final line = '${_timestamp()} ${level.name.toUpperCase()} [test] $message';
|
||||
// ignore: avoid_print
|
||||
print(line);
|
||||
for (final listener in _listeners) {
|
||||
|
||||
@@ -12,8 +12,10 @@ class PeriodicTicker {
|
||||
int? _intervalId;
|
||||
|
||||
void start(Duration interval, void Function() onTick) {
|
||||
_intervalId = web.window
|
||||
.setInterval((() => onTick()).toJS, interval.inMilliseconds.toJS);
|
||||
_intervalId = web.window.setInterval(
|
||||
(() => onTick()).toJS,
|
||||
interval.inMilliseconds.toJS,
|
||||
);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// Running veilid-core inside a plain `flutter test` process.
|
||||
//
|
||||
// A `flutter test` process has no plugins, and veilid-core startup needs
|
||||
// exactly one platform channel: `path_provider`, for its storage directory.
|
||||
// Mocking that channel starts core normally, which gives unit tests crypto
|
||||
// (keypairs, member ids, signing, nonces) and TableDB.
|
||||
//
|
||||
// Core does not attach here: no network, no DHT records, no peers. Tests
|
||||
// needing those belong in the integration harness.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'veilid_fixture.dart';
|
||||
|
||||
/// Point `path_provider` at a fresh temporary directory and return it.
|
||||
///
|
||||
/// Every method on that channel answers with a path, so one handler covers all
|
||||
/// of them. The directory is new on every call, so concurrent test processes
|
||||
/// never share a storage root.
|
||||
Directory mockVeilidStorageDirectories({String prefix = 'veilid_unit'}) {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
final dir = Directory.systemTemp.createTempSync(prefix);
|
||||
for (final channel in const [
|
||||
'plugins.flutter.io/path_provider',
|
||||
'plugins.flutter.io/path_provider_macos',
|
||||
'plugins.flutter.io/path_provider_linux',
|
||||
'plugins.flutter.io/path_provider_windows',
|
||||
'plugins.flutter.io/path_provider_android',
|
||||
]) {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
MethodChannel(channel),
|
||||
(call) async => dir.path,
|
||||
);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
/// A program name no concurrently-running test process can share.
|
||||
///
|
||||
/// [DefaultVeilidFixture] joins the program name into its table, protected and
|
||||
/// block store directories, so it is the isolation key: two processes sharing
|
||||
/// one share their stores. `flutter test` runs test files in separate
|
||||
/// processes, so the pid separates them. A Dart program holds at most one
|
||||
/// veilid instance, so no instance counter is needed on top.
|
||||
String veilidUnitProgramName([String base = 'VeilidUnitTest']) => '$base-$pid';
|
||||
|
||||
/// Start veilid-core for this test file and shut it down afterwards.
|
||||
///
|
||||
/// Call once at the top of `main()`. veilid-core is a process singleton, so
|
||||
/// this registers `setUpAll`/`tearDownAll`, not per-test hooks.
|
||||
///
|
||||
/// Startup is [DefaultVeilidFixture], the same one the integration tests use,
|
||||
/// so logging and config honour the same environment variables; this adds the
|
||||
/// mocked storage directory a pluginless process lacks and a per-process
|
||||
/// program name (see [veilidUnitProgramName]).
|
||||
///
|
||||
/// [base] only labels the run; the pid supplies uniqueness, so two files may
|
||||
/// share a base.
|
||||
void useVeilidUnitCore({String base = 'VeilidUnitTest'}) {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
late Directory storageDir;
|
||||
final programName = veilidUnitProgramName(base);
|
||||
final fixture = DefaultVeilidFixture(programName: programName);
|
||||
|
||||
setUpAll(() async {
|
||||
storageDir = mockVeilidStorageDirectories(prefix: programName);
|
||||
await fixture.setUp();
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
await fixture.tearDown();
|
||||
try {
|
||||
storageDir.deleteSync(recursive: true);
|
||||
} on FileSystemException {
|
||||
// A leftover temp directory is not worth failing a suite over
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -11,8 +11,7 @@ class UpdateProcessorFixture implements VeilidProcessorInterface {
|
||||
VeilidFixture veilidFixture;
|
||||
|
||||
@override
|
||||
ProcessorConnectionState processorConnectionState =
|
||||
ProcessorConnectionState(
|
||||
ProcessorConnectionState processorConnectionState = ProcessorConnectionState(
|
||||
attachment: VeilidStateAttachment(
|
||||
state: AttachmentState.detached,
|
||||
publicInternetReady: false,
|
||||
|
||||
@@ -3,5 +3,6 @@ library;
|
||||
|
||||
export 'src/log_fixture.dart';
|
||||
export 'src/ticker_fixture.dart';
|
||||
export 'src/unit_fixture.dart';
|
||||
export 'src/update_processor_fixture.dart';
|
||||
export 'src/veilid_fixture.dart';
|
||||
@@ -14,6 +14,13 @@ dependencies:
|
||||
web: ^1.1.1
|
||||
veilid:
|
||||
path: ../..
|
||||
# For the unit fixture, which mocks a platform channel and registers test
|
||||
# hooks. This package already depends on veilid, a Flutter plugin, so it was
|
||||
# never usable outside Flutter.
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^6.0.0
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
pushd example 2>/dev/null
|
||||
|
||||
# Cargo features come from the `hooks: user_defines:` block in example/pubspec.yaml;
|
||||
# hooks run under a fixed environment allowlist, so nothing can be passed from here.
|
||||
# Set cargo features in example/pubspec.yaml under `hooks: user_defines:`; hooks run
|
||||
# under a fixed environment allowlist, so this script cannot pass any through
|
||||
|
||||
# Default to the #common=debug log tag group unless the caller overrides LOG_DIRECTIVES
|
||||
case "$*" in
|
||||
|
||||
@@ -12,7 +12,7 @@ const knownVectors = [
|
||||
['foo', 'Zm9v'],
|
||||
['foob', 'Zm9vYg'],
|
||||
['fooba', 'Zm9vYmE'],
|
||||
['foobar', 'Zm9vYmFy']
|
||||
['foobar', 'Zm9vYmFy'],
|
||||
];
|
||||
|
||||
Future<void> _testEncodingKnownVector(Uint8List k, String v) async {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
// Renaming either side of the @DefaultAsset/assetName pair still compiles, and only
|
||||
// fails when the first FFI call runs.
|
||||
// Renaming either side of the @DefaultAsset/assetName pair still compiles and
|
||||
// fails only at the first FFI call.
|
||||
void testNativeAssetResolves() {
|
||||
expect(Veilid.instance.veilidVersionString(), isNotEmpty);
|
||||
expect(Veilid.instance.veilidFeatures(), isNotEmpty);
|
||||
|
||||
@@ -13,12 +13,14 @@ ValueSubkeyRange? vsrIntersect(ValueSubkeyRange a, ValueSubkeyRange b) =>
|
||||
a.intersect(b);
|
||||
|
||||
List<ValueSubkeyRange> lvsrUnion(
|
||||
List<ValueSubkeyRange> a, List<ValueSubkeyRange> b) =>
|
||||
a.unionSubkeys(b);
|
||||
List<ValueSubkeyRange> a,
|
||||
List<ValueSubkeyRange> b,
|
||||
) => a.unionSubkeys(b);
|
||||
|
||||
List<ValueSubkeyRange> lvsrIntersect(
|
||||
List<ValueSubkeyRange> a, List<ValueSubkeyRange> b) =>
|
||||
a.intersectSubkeys(b);
|
||||
List<ValueSubkeyRange> a,
|
||||
List<ValueSubkeyRange> b,
|
||||
) => a.intersectSubkeys(b);
|
||||
|
||||
Future<void> testValueSubkeyRange() async {
|
||||
final a = ValueSubkeyRange.single(1);
|
||||
@@ -45,7 +47,11 @@ Future<void> testValueSubkeyRangeList() async {
|
||||
expectCommute(lvsrUnion, a, a, a);
|
||||
expectCommute(lvsrUnion, a, b, [const ValueSubkeyRange(low: 1, high: 3)]);
|
||||
expectCommute<List<ValueSubkeyRange>>(
|
||||
lvsrUnion, a, c, ListValueSubkeyRangeExt.fromIntPairs([(1, 1), (3, 4)]));
|
||||
lvsrUnion,
|
||||
a,
|
||||
c,
|
||||
ListValueSubkeyRangeExt.fromIntPairs([(1, 1), (3, 4)]),
|
||||
);
|
||||
expectCommute(lvsrUnion, b, c, [const ValueSubkeyRange(low: 2, high: 4)]);
|
||||
|
||||
const d = [ValueSubkeyRange(low: 0, high: 3)];
|
||||
@@ -60,8 +66,12 @@ Future<void> testValueSubkeyRangeList() async {
|
||||
|
||||
expectCommute(lvsrUnion, e, f, g);
|
||||
|
||||
final h = ListValueSubkeyRangeExt.fromIntPairs(
|
||||
[(2, 5), (10, 10), (12, 14), (16, 18)]);
|
||||
final h = ListValueSubkeyRangeExt.fromIntPairs([
|
||||
(2, 5),
|
||||
(10, 10),
|
||||
(12, 14),
|
||||
(16, 18),
|
||||
]);
|
||||
expectCommute(lvsrIntersect, e, f, h);
|
||||
|
||||
expectCommute<List<ValueSubkeyRange>>(lvsrUnion, [], [], []);
|
||||
|
||||
Reference in new issue
Block a user