SHA256
Зафиксировать все текущие изменения проекта
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import { Program } from "@coral-xyz/anchor";
|
||||
import {
|
||||
ComputeBudgetProgram,
|
||||
Ed25519Program,
|
||||
PublicKey,
|
||||
SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||
@@ -21,8 +22,10 @@ const BLOCK_TYPE_BLOCKCHAIN_REGISTRY = 3;
|
||||
const BLOCK_TYPE_SERVER_PROFILE = 30;
|
||||
const BLOCK_TYPE_ACCESS_SERVERS = 40;
|
||||
const BLOCK_TYPE_TRUSTED_STATE = 50;
|
||||
const BLOCK_TYPE_SESSIONS = 55;
|
||||
const BLOCK_VERSION_0 = 0;
|
||||
const BLOCKCHAIN_TYPE_MAIN_USER = 1;
|
||||
const SESSIONS_MODE_MIXED = 1;
|
||||
|
||||
const LIMIT_STEP = 10_000n;
|
||||
const START_BONUS_LIMIT = 100_000n;
|
||||
@@ -32,6 +35,13 @@ const SHINE_PAYMENTS_PROGRAM_ID = new PublicKey(
|
||||
);
|
||||
const SHINE_PAYMENTS_INFLOW_VAULT_SEED = "shine_payments_inflow_vault";
|
||||
|
||||
type SessionRecord = {
|
||||
sessionType: number;
|
||||
sessionVersion: number;
|
||||
sessionName: string;
|
||||
sessionPubKey: PublicKey;
|
||||
};
|
||||
|
||||
type MutableFields = {
|
||||
deviceKey: PublicKey;
|
||||
blockchainPublicKey: PublicKey;
|
||||
@@ -42,10 +52,13 @@ type MutableFields = {
|
||||
lastBlockSignature: Buffer;
|
||||
arweaveTxId: string;
|
||||
isServer: boolean;
|
||||
serverKey: PublicKey;
|
||||
addressFormatType: number;
|
||||
addressFormatVersion: number;
|
||||
serverAddress: string;
|
||||
syncServers: string[];
|
||||
accessServers: string[];
|
||||
sessionsMode: number;
|
||||
sessions: SessionRecord[];
|
||||
trustedCount: number;
|
||||
};
|
||||
|
||||
@@ -69,10 +82,13 @@ type UnsignedRecord = {
|
||||
arweaveTxId: string;
|
||||
};
|
||||
isServer: boolean;
|
||||
serverKey: PublicKey;
|
||||
addressFormatType: number;
|
||||
addressFormatVersion: number;
|
||||
serverAddress: string;
|
||||
syncServers: string[];
|
||||
accessServers: string[];
|
||||
sessionsMode: number;
|
||||
sessions: SessionRecord[];
|
||||
trustedCount: number;
|
||||
};
|
||||
|
||||
@@ -98,7 +114,7 @@ function serializeUnsignedRecord(r: UnsignedRecord): Buffer {
|
||||
out.push(MAGIC);
|
||||
out.push(Buffer.from([FORMAT_MAJOR]));
|
||||
out.push(Buffer.from([FORMAT_MINOR]));
|
||||
out.push(Buffer.alloc(2, 0)); // record_len placeholder
|
||||
out.push(Buffer.alloc(2, 0));
|
||||
|
||||
out.push(u64le(r.createdAtMs));
|
||||
out.push(u64le(r.updatedAtMs));
|
||||
@@ -106,7 +122,7 @@ function serializeUnsignedRecord(r: UnsignedRecord): Buffer {
|
||||
out.push(r.prevRecordHash);
|
||||
out.push(strBytes(r.login));
|
||||
|
||||
out.push(Buffer.from([r.isServer ? 6 : 5]));
|
||||
out.push(Buffer.from([r.isServer ? 7 : 6]));
|
||||
out.push(Buffer.from([BLOCK_TYPE_ROOT_KEY, BLOCK_VERSION_0]));
|
||||
out.push(r.rootKey.toBuffer());
|
||||
out.push(Buffer.from([BLOCK_TYPE_DEVICE_KEY, BLOCK_VERSION_0]));
|
||||
@@ -129,21 +145,23 @@ function serializeUnsignedRecord(r: UnsignedRecord): Buffer {
|
||||
|
||||
if (r.isServer) {
|
||||
out.push(Buffer.from([BLOCK_TYPE_SERVER_PROFILE, BLOCK_VERSION_0, 1]));
|
||||
out.push(r.serverKey.toBuffer());
|
||||
out.push(Buffer.from([r.addressFormatType, r.addressFormatVersion]));
|
||||
out.push(strBytes(r.serverAddress));
|
||||
out.push(Buffer.from([r.syncServers.length]));
|
||||
for (const s of r.syncServers) {
|
||||
out.push(strBytes(s));
|
||||
}
|
||||
for (const s of r.syncServers) out.push(strBytes(s));
|
||||
}
|
||||
|
||||
out.push(Buffer.from([BLOCK_TYPE_ACCESS_SERVERS, BLOCK_VERSION_0]));
|
||||
out.push(Buffer.from([r.accessServers.length]));
|
||||
for (const s of r.accessServers) {
|
||||
out.push(strBytes(s));
|
||||
out.push(Buffer.from([BLOCK_TYPE_ACCESS_SERVERS, BLOCK_VERSION_0, r.accessServers.length]));
|
||||
for (const s of r.accessServers) out.push(strBytes(s));
|
||||
|
||||
out.push(Buffer.from([BLOCK_TYPE_SESSIONS, BLOCK_VERSION_0, r.sessionsMode, r.sessions.length]));
|
||||
for (const s of r.sessions) {
|
||||
out.push(Buffer.from([s.sessionType, s.sessionVersion]));
|
||||
out.push(strBytes(s.sessionName));
|
||||
out.push(s.sessionPubKey.toBuffer());
|
||||
}
|
||||
out.push(Buffer.from([BLOCK_TYPE_TRUSTED_STATE, BLOCK_VERSION_0]));
|
||||
out.push(Buffer.from([r.trustedCount]));
|
||||
|
||||
out.push(Buffer.from([BLOCK_TYPE_TRUSTED_STATE, BLOCK_VERSION_0, r.trustedCount]));
|
||||
|
||||
const unsigned = Buffer.concat(out);
|
||||
const recordLen = unsigned.length + 64;
|
||||
@@ -191,9 +209,7 @@ describe("shine_users e2e", () => {
|
||||
SHINE_PAYMENTS_PROGRAM_ID
|
||||
);
|
||||
|
||||
const economyAi = await provider.connection.getAccountInfo(
|
||||
usersEconomyConfigPda
|
||||
);
|
||||
const economyAi = await provider.connection.getAccountInfo(usersEconomyConfigPda);
|
||||
if (!economyAi) {
|
||||
await program.methods
|
||||
.initUsersEconomyConfig()
|
||||
@@ -207,10 +223,28 @@ describe("shine_users e2e", () => {
|
||||
const root = anchor.web3.Keypair.generate();
|
||||
const blockchain = anchor.web3.Keypair.generate();
|
||||
const deviceKey = anchor.web3.Keypair.generate().publicKey;
|
||||
const serverKey1 = anchor.web3.Keypair.generate().publicKey;
|
||||
const serverKey2 = anchor.web3.Keypair.generate().publicKey;
|
||||
const blockchainName = `${login}-001`;
|
||||
|
||||
const createFields: MutableFields = {
|
||||
deviceKey,
|
||||
blockchainPublicKey: blockchain.publicKey,
|
||||
blockchainName,
|
||||
usedBytes: 0n,
|
||||
lastBlockNumber: 0,
|
||||
lastBlockHash: ZERO_HASH,
|
||||
lastBlockSignature: Buffer.alloc(64, 0),
|
||||
arweaveTxId: "",
|
||||
isServer: true,
|
||||
addressFormatType: 1,
|
||||
addressFormatVersion: 0,
|
||||
serverAddress: "https://srv-1.local",
|
||||
syncServers: ["sync_srv_1", "sync_srv_2"],
|
||||
accessServers: ["access_srv_1"],
|
||||
sessionsMode: SESSIONS_MODE_MIXED,
|
||||
sessions: [],
|
||||
trustedCount: 0,
|
||||
};
|
||||
|
||||
const createdAtMs = BigInt(Date.now());
|
||||
const additionalLimitCreate = 20_000n;
|
||||
expect(additionalLimitCreate % LIMIT_STEP).eq(0n);
|
||||
@@ -228,27 +262,29 @@ describe("shine_users e2e", () => {
|
||||
blockchainName,
|
||||
blockchainPublicKey: blockchain.publicKey,
|
||||
paidLimitBytes: START_BONUS_LIMIT + additionalLimitCreate,
|
||||
usedBytes: 0n,
|
||||
lastBlockNumber: 0,
|
||||
lastBlockHash: ZERO_HASH,
|
||||
usedBytes: createFields.usedBytes,
|
||||
lastBlockNumber: createFields.lastBlockNumber,
|
||||
lastBlockHash: createFields.lastBlockHash,
|
||||
lastBlockSignature: Buffer.alloc(64, 0),
|
||||
arweaveTxId: "",
|
||||
arweaveTxId: createFields.arweaveTxId,
|
||||
},
|
||||
isServer: true,
|
||||
serverKey: serverKey1,
|
||||
serverAddress: "https://srv-1.local",
|
||||
syncServers: ["sync_srv_1", "sync_srv_2"],
|
||||
accessServers: ["access_srv_1"],
|
||||
trustedCount: 0,
|
||||
isServer: createFields.isServer,
|
||||
addressFormatType: createFields.addressFormatType,
|
||||
addressFormatVersion: createFields.addressFormatVersion,
|
||||
serverAddress: createFields.serverAddress,
|
||||
syncServers: createFields.syncServers,
|
||||
accessServers: createFields.accessServers,
|
||||
sessionsMode: createFields.sessionsMode,
|
||||
sessions: createFields.sessions,
|
||||
trustedCount: createFields.trustedCount,
|
||||
};
|
||||
const createLastBlockHash = sha256(serializeLastBlockState(createRecord));
|
||||
const createLastBlockEdIx = Ed25519Program.createInstructionWithPrivateKey({
|
||||
privateKey: blockchain.secretKey,
|
||||
message: createLastBlockHash,
|
||||
});
|
||||
createRecord.blockchain.lastBlockSignature = extractSigFromEdIx(
|
||||
Buffer.from(createLastBlockEdIx.data)
|
||||
);
|
||||
createRecord.blockchain.lastBlockSignature = extractSigFromEdIx(Buffer.from(createLastBlockEdIx.data));
|
||||
createFields.lastBlockSignature = createRecord.blockchain.lastBlockSignature;
|
||||
|
||||
const createUnsigned = serializeUnsignedRecord(createRecord);
|
||||
const createHash = sha256(createUnsigned);
|
||||
@@ -265,22 +301,28 @@ describe("shine_users e2e", () => {
|
||||
createdAtMs: new anchor.BN(createdAtMs.toString()),
|
||||
additionalLimit: new anchor.BN(additionalLimitCreate.toString()),
|
||||
fields: {
|
||||
deviceKey,
|
||||
blockchainPublicKey: blockchain.publicKey,
|
||||
blockchainName,
|
||||
usedBytes: new anchor.BN(
|
||||
createRecord.blockchain.usedBytes.toString()
|
||||
),
|
||||
lastBlockNumber: createRecord.blockchain.lastBlockNumber,
|
||||
lastBlockHash: createRecord.blockchain.lastBlockHash,
|
||||
lastBlockSignature: createRecord.blockchain.lastBlockSignature,
|
||||
arweaveTxId: "",
|
||||
isServer: true,
|
||||
serverKey: serverKey1,
|
||||
serverAddress: "https://srv-1.local",
|
||||
syncServers: ["sync_srv_1", "sync_srv_2"],
|
||||
accessServers: ["access_srv_1"],
|
||||
trustedCount: 0,
|
||||
deviceKey: createFields.deviceKey,
|
||||
blockchainPublicKey: createFields.blockchainPublicKey,
|
||||
blockchainName: createFields.blockchainName,
|
||||
usedBytes: new anchor.BN(createFields.usedBytes.toString()),
|
||||
lastBlockNumber: createFields.lastBlockNumber,
|
||||
lastBlockHash: createFields.lastBlockHash,
|
||||
lastBlockSignature: createFields.lastBlockSignature,
|
||||
arweaveTxId: createFields.arweaveTxId,
|
||||
isServer: createFields.isServer,
|
||||
addressFormatType: createFields.addressFormatType,
|
||||
addressFormatVersion: createFields.addressFormatVersion,
|
||||
serverAddress: createFields.serverAddress,
|
||||
syncServers: createFields.syncServers,
|
||||
accessServers: createFields.accessServers,
|
||||
sessionsMode: createFields.sessionsMode,
|
||||
sessions: createFields.sessions.map((s) => ({
|
||||
sessionType: s.sessionType,
|
||||
sessionVersion: s.sessionVersion,
|
||||
sessionName: s.sessionName,
|
||||
sessionPubKey: s.sessionPubKey,
|
||||
})),
|
||||
trustedCount: createFields.trustedCount,
|
||||
},
|
||||
signature: createSig,
|
||||
})
|
||||
@@ -293,10 +335,7 @@ describe("shine_users e2e", () => {
|
||||
})
|
||||
.instruction();
|
||||
|
||||
await provider.sendAndConfirm(
|
||||
new Transaction().add(createEdIx, createLastBlockEdIx, createIx),
|
||||
[]
|
||||
);
|
||||
await provider.sendAndConfirm(new Transaction().add(createEdIx, createLastBlockEdIx, createIx), []);
|
||||
|
||||
const createAcc = await provider.connection.getAccountInfo(userPda);
|
||||
expect(createAcc).not.eq(null);
|
||||
@@ -304,6 +343,26 @@ describe("shine_users e2e", () => {
|
||||
|
||||
const additionalLimitUpdate = 30_000n;
|
||||
expect(additionalLimitUpdate % LIMIT_STEP).eq(0n);
|
||||
const updatedDeviceKey = anchor.web3.Keypair.generate().publicKey;
|
||||
const updateFields: MutableFields = {
|
||||
deviceKey: updatedDeviceKey,
|
||||
blockchainPublicKey: blockchain.publicKey,
|
||||
blockchainName,
|
||||
usedBytes: 512n,
|
||||
lastBlockNumber: 1,
|
||||
lastBlockHash: sha256(Buffer.from("first-shine-block")),
|
||||
lastBlockSignature: Buffer.alloc(64, 0),
|
||||
arweaveTxId: "",
|
||||
isServer: true,
|
||||
addressFormatType: 1,
|
||||
addressFormatVersion: 0,
|
||||
serverAddress: "https://srv-2.local",
|
||||
syncServers: ["sync_srv_3"],
|
||||
accessServers: ["access_srv_2", "access_srv_3"],
|
||||
sessionsMode: SESSIONS_MODE_MIXED,
|
||||
sessions: [],
|
||||
trustedCount: 0,
|
||||
};
|
||||
|
||||
const updateRecord: UnsignedRecord = {
|
||||
createdAtMs,
|
||||
@@ -312,34 +371,35 @@ describe("shine_users e2e", () => {
|
||||
prevRecordHash: sha256(createUnsigned),
|
||||
login,
|
||||
rootKey: root.publicKey,
|
||||
deviceKey: anchor.web3.Keypair.generate().publicKey,
|
||||
deviceKey: updatedDeviceKey,
|
||||
blockchain: {
|
||||
blockchainType: BLOCKCHAIN_TYPE_MAIN_USER,
|
||||
blockchainName,
|
||||
blockchainPublicKey: blockchain.publicKey,
|
||||
paidLimitBytes:
|
||||
START_BONUS_LIMIT + additionalLimitCreate + additionalLimitUpdate,
|
||||
usedBytes: 512n,
|
||||
lastBlockNumber: 1,
|
||||
lastBlockHash: sha256(Buffer.from("first-shine-block")),
|
||||
paidLimitBytes: START_BONUS_LIMIT + additionalLimitCreate + additionalLimitUpdate,
|
||||
usedBytes: updateFields.usedBytes,
|
||||
lastBlockNumber: updateFields.lastBlockNumber,
|
||||
lastBlockHash: updateFields.lastBlockHash,
|
||||
lastBlockSignature: Buffer.alloc(64, 0),
|
||||
arweaveTxId: "",
|
||||
arweaveTxId: updateFields.arweaveTxId,
|
||||
},
|
||||
isServer: true,
|
||||
serverKey: serverKey2,
|
||||
serverAddress: "https://srv-2.local",
|
||||
syncServers: ["sync_srv_3"],
|
||||
accessServers: ["access_srv_2", "access_srv_3"],
|
||||
trustedCount: 0,
|
||||
isServer: updateFields.isServer,
|
||||
addressFormatType: updateFields.addressFormatType,
|
||||
addressFormatVersion: updateFields.addressFormatVersion,
|
||||
serverAddress: updateFields.serverAddress,
|
||||
syncServers: updateFields.syncServers,
|
||||
accessServers: updateFields.accessServers,
|
||||
sessionsMode: updateFields.sessionsMode,
|
||||
sessions: updateFields.sessions,
|
||||
trustedCount: updateFields.trustedCount,
|
||||
};
|
||||
const updateLastBlockHash = sha256(serializeLastBlockState(updateRecord));
|
||||
const updateLastBlockEdIx = Ed25519Program.createInstructionWithPrivateKey({
|
||||
privateKey: blockchain.secretKey,
|
||||
message: updateLastBlockHash,
|
||||
});
|
||||
updateRecord.blockchain.lastBlockSignature = extractSigFromEdIx(
|
||||
Buffer.from(updateLastBlockEdIx.data)
|
||||
);
|
||||
updateRecord.blockchain.lastBlockSignature = extractSigFromEdIx(Buffer.from(updateLastBlockEdIx.data));
|
||||
updateFields.lastBlockSignature = updateRecord.blockchain.lastBlockSignature;
|
||||
|
||||
const updateUnsigned = serializeUnsignedRecord(updateRecord);
|
||||
const updateHash = sha256(updateUnsigned);
|
||||
@@ -359,22 +419,28 @@ describe("shine_users e2e", () => {
|
||||
prevHash: sha256(createUnsigned),
|
||||
additionalLimit: new anchor.BN(additionalLimitUpdate.toString()),
|
||||
fields: {
|
||||
deviceKey: updateRecord.deviceKey,
|
||||
blockchainPublicKey: updateRecord.blockchain.blockchainPublicKey,
|
||||
blockchainName,
|
||||
usedBytes: new anchor.BN(
|
||||
updateRecord.blockchain.usedBytes.toString()
|
||||
),
|
||||
lastBlockNumber: updateRecord.blockchain.lastBlockNumber,
|
||||
lastBlockHash: updateRecord.blockchain.lastBlockHash,
|
||||
lastBlockSignature: updateRecord.blockchain.lastBlockSignature,
|
||||
arweaveTxId: "",
|
||||
isServer: true,
|
||||
serverKey: serverKey2,
|
||||
serverAddress: "https://srv-2.local",
|
||||
syncServers: ["sync_srv_3"],
|
||||
accessServers: ["access_srv_2", "access_srv_3"],
|
||||
trustedCount: 0,
|
||||
deviceKey: updateFields.deviceKey,
|
||||
blockchainPublicKey: updateFields.blockchainPublicKey,
|
||||
blockchainName: updateFields.blockchainName,
|
||||
usedBytes: new anchor.BN(updateFields.usedBytes.toString()),
|
||||
lastBlockNumber: updateFields.lastBlockNumber,
|
||||
lastBlockHash: updateFields.lastBlockHash,
|
||||
lastBlockSignature: updateFields.lastBlockSignature,
|
||||
arweaveTxId: updateFields.arweaveTxId,
|
||||
isServer: updateFields.isServer,
|
||||
addressFormatType: updateFields.addressFormatType,
|
||||
addressFormatVersion: updateFields.addressFormatVersion,
|
||||
serverAddress: updateFields.serverAddress,
|
||||
syncServers: updateFields.syncServers,
|
||||
accessServers: updateFields.accessServers,
|
||||
sessionsMode: updateFields.sessionsMode,
|
||||
sessions: updateFields.sessions.map((s) => ({
|
||||
sessionType: s.sessionType,
|
||||
sessionVersion: s.sessionVersion,
|
||||
sessionName: s.sessionName,
|
||||
sessionPubKey: s.sessionPubKey,
|
||||
})),
|
||||
trustedCount: updateFields.trustedCount,
|
||||
},
|
||||
signature: updateSig,
|
||||
})
|
||||
@@ -387,8 +453,10 @@ describe("shine_users e2e", () => {
|
||||
})
|
||||
.instruction();
|
||||
|
||||
const updateComputeIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 800_000 });
|
||||
const updateHeapIx = ComputeBudgetProgram.requestHeapFrame({ bytes: 262_144 });
|
||||
await provider.sendAndConfirm(
|
||||
new Transaction().add(updateEdIx, updateLastBlockEdIx, updateIx),
|
||||
new Transaction().add(updateComputeIx, updateHeapIx, updateEdIx, updateLastBlockEdIx, updateIx),
|
||||
[]
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user