Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/6.1.0' into 9004-upd-nft-mod-internal-functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmartin committed Oct 9, 2023
2 parents 7321540 + 2eabd20 commit 5fbae3f
Show file tree
Hide file tree
Showing 32 changed files with 913 additions and 834 deletions.
1 change: 0 additions & 1 deletion elements/lisk-chain/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export const GENESIS_BLOCK_TRANSACTION_ROOT = EMPTY_HASH;
export const TAG_BLOCK_HEADER = utils.createMessageTag('BH');
export const TAG_TRANSACTION = utils.createMessageTag('TX');

// TODO: Actual size TBD
export const MAX_ASSET_DATA_SIZE_BYTES = 18;
export const SIGNATURE_LENGTH_BYTES = 64;

Expand Down
13 changes: 2 additions & 11 deletions elements/lisk-chain/src/state_store/state_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,10 @@ export class StateStore {
this._latestSnapshotId = -1;
}

// TODO: Remove accepting number for subStorePrefix
public getStore(storePrefix: Buffer, subStorePrefix: Buffer | number): StateStore {
let storePrefixBuffer: Buffer;
if (typeof subStorePrefix === 'number') {
storePrefixBuffer = Buffer.alloc(2);
storePrefixBuffer.writeUInt16BE(subStorePrefix, 0);
} else {
storePrefixBuffer = subStorePrefix;
}

public getStore(storePrefix: Buffer, subStorePrefix: Buffer): StateStore {
const subStore = new StateStore(
this._db,
Buffer.concat([DB_KEY_STATE_STORE, storePrefix, storePrefixBuffer]),
Buffer.concat([DB_KEY_STATE_STORE, storePrefix, subStorePrefix]),
this._cache,
);

Expand Down
2 changes: 1 addition & 1 deletion elements/lisk-chain/test/unit/chain.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('chain', () => {
beforeEach(async () => {
stateStore = new StateStore(db);
jest.spyOn(stateStore, 'finalize');
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), 0);
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), Buffer.from([0, 0]));
await subStore.set(utils.getRandomBytes(20), utils.getRandomBytes(100));
batch = new Batch();
jest.spyOn(batch, 'set');
Expand Down
61 changes: 33 additions & 28 deletions elements/lisk-chain/test/unit/state_store/state_store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ const sampleSchema = {

describe('state store', () => {
let moduleID = utils.intToBuffer(2, 4);

const storePrefix = 0;
const storePrefixBuffer = Buffer.alloc(2);
storePrefixBuffer.writeUInt16BE(storePrefix, 0);

const anotherStorePrefix = 1;
const anotherStorePrefixBuffer = Buffer.alloc(2);
anotherStorePrefixBuffer.writeUInt16BE(anotherStorePrefix, 0);

const existingKey = utils.getRandomBytes(20);
const existingKey2 = utils.getRandomBytes(20);
const existingValue = utils.getRandomBytes(64);
Expand All @@ -43,8 +51,6 @@ describe('state store', () => {
beforeEach(async () => {
db = new InMemoryDatabase();
stateStore = new StateStore(db);
const storePrefixBuffer = Buffer.alloc(2);
storePrefixBuffer.writeUInt16BE(storePrefix, 0);
await db.set(
Buffer.concat([stateStore['_prefix'], moduleID, storePrefixBuffer, existingKey]),
existingValue,
Expand All @@ -59,25 +65,25 @@ describe('state store', () => {
it('should keep the same cache as the original state store', async () => {
const address = utils.getRandomBytes(20);
const value = utils.getRandomBytes(64);
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), 0);
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), storePrefixBuffer);
await subStore.set(address, value);
// create different store from the state store
const newSubStore = stateStore.getStore(utils.intToBuffer(2, 4), 0);
const newSubStore = stateStore.getStore(utils.intToBuffer(2, 4), storePrefixBuffer);
const valueFromNewStore = await newSubStore.get(address);

expect(valueFromNewStore).toEqual(value);
});

it('should append the prefix', () => {
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), 0);
const subStore = stateStore.getStore(utils.intToBuffer(2, 4), storePrefixBuffer);
// db prefix(1) + moduleID(4) + storePrefix(2)
expect(subStore['_prefix']).toHaveLength(1 + 4 + 2);
});
});

describe('get', () => {
it('should get from the cache if the key already exist', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
const newKey = utils.getRandomBytes(20);
await subStore.set(newKey, utils.getRandomBytes(10));
jest.spyOn(db, 'get');
Expand All @@ -89,7 +95,7 @@ describe('state store', () => {

it('should get from the database if the key does not exist', async () => {
jest.spyOn(db, 'get');
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

const value = await subStore.get(existingKey);

Expand All @@ -98,7 +104,7 @@ describe('state store', () => {
});

it('should return copied value', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

const value = await subStore.get(existingKey);
value[0] = 233;
Expand All @@ -109,7 +115,7 @@ describe('state store', () => {
});

it('should throw not found error if deleted in the key', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.del(existingKey);

await expect(subStore.get(existingKey)).rejects.toThrow(NotFoundError);
Expand All @@ -120,7 +126,7 @@ describe('state store', () => {
it('should return decoded value', async () => {
const address = utils.getRandomBytes(20);
const encodedValue = codec.encode(sampleSchema, { address });
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.set(address, encodedValue);

const value = await subStore.getWithSchema<Record<string, unknown>>(address, sampleSchema);
Expand All @@ -133,7 +139,7 @@ describe('state store', () => {
it('should update the cached value if it exist in the cache', async () => {
const address = utils.getRandomBytes(20);
const value = utils.getRandomBytes(50);
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

await subStore.set(address, value);
const updatingValue = await subStore.get(address);
Expand All @@ -150,7 +156,7 @@ describe('state store', () => {
jest.spyOn(db, 'get');
const address = utils.getRandomBytes(20);
const value = utils.getRandomBytes(50);
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

await subStore.set(address, value);
const updatingValue = await subStore.get(address);
Expand All @@ -164,7 +170,7 @@ describe('state store', () => {
it('should set encoded value', async () => {
const address = utils.getRandomBytes(20);
const encodedValue = codec.encode(sampleSchema, { address });
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.setWithSchema(address, { address }, sampleSchema);

const value = await subStore.get(address);
Expand All @@ -178,7 +184,7 @@ describe('state store', () => {
const value = utils.getRandomBytes(50);

it('should mark as deleted if it exists in the cache', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

await subStore.set(address, value);
await subStore.del(address);
Expand All @@ -188,7 +194,7 @@ describe('state store', () => {

it('should cache the original value and mark as deleted if it does not in the cache', async () => {
jest.spyOn(db, 'get');
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.del(existingKey);

expect(db.get).toHaveReturnedTimes(1);
Expand All @@ -198,7 +204,7 @@ describe('state store', () => {

describe('iterate', () => {
it('should return all the key-values with the prefix', async () => {
const subStore = stateStore.getStore(moduleID, 1);
const subStore = stateStore.getStore(moduleID, anotherStorePrefixBuffer);
await subStore.set(Buffer.from([0]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([1]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([2]), utils.getRandomBytes(40));
Expand All @@ -214,9 +220,9 @@ describe('state store', () => {
});

it('should return all the key-values with the prefix in reverse order', async () => {
const existingStore = stateStore.getStore(moduleID, storePrefix);
const existingStore = stateStore.getStore(moduleID, storePrefixBuffer);
await existingStore.set(Buffer.from([0]), utils.getRandomBytes(40));
const subStore = stateStore.getStore(moduleID, 1);
const subStore = stateStore.getStore(moduleID, anotherStorePrefixBuffer);
await subStore.set(Buffer.from([0]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([1]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([2]), utils.getRandomBytes(40));
Expand All @@ -234,7 +240,7 @@ describe('state store', () => {
});

it('should not return the deleted values', async () => {
const subStore = stateStore.getStore(moduleID, 1);
const subStore = stateStore.getStore(moduleID, anotherStorePrefixBuffer);
await subStore.set(Buffer.from([0]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([1]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([2]), utils.getRandomBytes(40));
Expand All @@ -252,7 +258,7 @@ describe('state store', () => {

it('should return the updated values in the cache', async () => {
const expectedValue = Buffer.from('random');
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.set(Buffer.from([0]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([1]), utils.getRandomBytes(40));
await subStore.set(Buffer.from([2]), utils.getRandomBytes(40));
Expand All @@ -273,7 +279,7 @@ describe('state store', () => {
it('should return decoded value', async () => {
const address = utils.getRandomBytes(20);
const encodedValue = codec.encode(sampleSchema, { address });
const subStore = stateStore.getStore(moduleID, 1);
const subStore = stateStore.getStore(moduleID, anotherStorePrefixBuffer);
await subStore.set(Buffer.from([0]), encodedValue);
await subStore.set(Buffer.from([1]), encodedValue);
await subStore.set(Buffer.from([2]), encodedValue);
Expand All @@ -294,7 +300,7 @@ describe('state store', () => {

describe('snapshot', () => {
it('should not change the snapshot data when other operation is triggered', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
subStore.createSnapshot();
const expected = utils.getRandomBytes(64);
await subStore.set(Buffer.from([0]), expected);
Expand All @@ -305,7 +311,7 @@ describe('state store', () => {
});

it('should restore to snapshot value when the restore is called', async () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
const id = subStore.createSnapshot();
await subStore.set(Buffer.from([0]), utils.getRandomBytes(64));
await subStore.del(existingKey);
Expand All @@ -318,15 +324,15 @@ describe('state store', () => {
});

it('should throw an error when restoring with an invalid snapshot ID', () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

expect(() => subStore.restoreSnapshot(100)).toThrow(
'Invalid snapshot ID. Cannot revert to an older snapshot.',
);
});

it('should throw an error when restoring without taking a snapshot first', () => {
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);

expect(() => subStore.restoreSnapshot(0)).toThrow(
'Invalid snapshot ID. Cannot revert to an older snapshot.',
Expand All @@ -348,7 +354,6 @@ describe('state store', () => {
const getKey = (mID: number, prefix: number) => {
moduleID = Buffer.alloc(4);
moduleID.writeInt32BE(mID, 0);
const storePrefixBuffer = Buffer.alloc(2);
storePrefixBuffer.writeUInt16BE(prefix, 0);
return Buffer.concat([moduleID, storePrefixBuffer]);
};
Expand All @@ -358,10 +363,10 @@ describe('state store', () => {

beforeEach(async () => {
data = [getRandomData(), getRandomData(), getRandomData()];
const subStore = stateStore.getStore(moduleID, storePrefix);
const subStore = stateStore.getStore(moduleID, storePrefixBuffer);
await subStore.set(existingKey, utils.getRandomBytes(40));
await subStore.del(existingKey2);
const anotherStore = stateStore.getStore(moduleID, 1);
const anotherStore = stateStore.getStore(moduleID, anotherStorePrefixBuffer);
for (const sample of data) {
await anotherStore.set(sample.key, sample.value);
}
Expand Down
14 changes: 14 additions & 0 deletions elements/lisk-chain/test/unit/transactions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ describe('blocks/transactions', () => {
expect(() => transaction.validate()).not.toThrow();
});

it('should not throw an error if params length is less than MAX_PARAMS_SIZE', () => {
transaction = new Transaction({
module: 'token',
command: 'transfer',
fee: BigInt(613000),
// 126 is the size of other properties
params: utils.getRandomBytes(MAX_PARAMS_SIZE - 1),
nonce: BigInt(2),
senderPublicKey: utils.getRandomBytes(32),
signatures: [utils.getRandomBytes(64)],
});
expect(() => transaction.validate()).not.toThrow();
});

it('should throw when module name is invalid', () => {
transaction = new Transaction({
module: 'token_mod',
Expand Down
4 changes: 2 additions & 2 deletions framework/src/engine/bft/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export const MODULE_STORE_PREFIX_BFT = Buffer.from([0, 0, 0, 0]);
export const ED25519_PUBLIC_KEY_LENGTH = 32;
export const BLS_PUBLIC_KEY_LENGTH = 48;
export const EMPTY_BLS_KEY = Buffer.alloc(BLS_PUBLIC_KEY_LENGTH, 0);
export const STORE_PREFIX_BFT_PARAMETERS = 0x0000;
export const STORE_PREFIX_BFT_VOTES = 0x8000;
export const STORE_PREFIX_BFT_PARAMETERS = Buffer.from([0x00, 0x00]);
export const STORE_PREFIX_BFT_VOTES = Buffer.from([0x80, 0x00]);
export const EMPTY_KEY = Buffer.alloc(0);
export const MAX_UINT32 = 2 ** 32 - 1;

Expand Down
4 changes: 2 additions & 2 deletions framework/src/engine/consensus/consensus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { ApplyPenaltyError } from '../../errors';
import { AbortError, ApplyPenaltyAndRestartError, RestartError } from './synchronizer/errors';
import { BlockExecutor } from './synchronizer/type';
import { Network } from '../network';
import { NetworkEndpoint, EndpointArgs } from './network_endpoint';
import { NetworkEndpoint } from './network_endpoint';
import { LegacyNetworkEndpoint } from '../legacy/network_endpoint';
import { EventPostBlockData, postBlockEventSchema } from './schema';
import {
Expand Down Expand Up @@ -158,7 +158,7 @@ export class Consensus {
network: this._network,
db: this._db,
commitPool: this._commitPool,
} as EndpointArgs); // TODO: Remove casting in issue where commitPool is added here
});
this._legacyEndpoint = new LegacyNetworkEndpoint({
logger: this._logger,
network: this._network,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,7 @@ import { getMainchainID } from './utils';
export abstract class BaseInteroperabilityMethod<
T extends BaseInteroperabilityInternalMethod,
> extends BaseMethod {
protected _tokenMethod!: TokenMethod & {
payMessageFee: (
context: MethodContext,
payFromAddress: Buffer,
fee: bigint,
receivingChainID: Buffer,
) => Promise<void>;
};
protected _tokenMethod!: TokenMethod;

public constructor(
stores: NamedRegistry,
Expand All @@ -55,17 +48,7 @@ export abstract class BaseInteroperabilityMethod<
super(stores, events);
}

public addDependencies(
tokenMethod: TokenMethod & {
// TODO: Remove this after token module update
payMessageFee: (
context: MethodContext,
payFromAddress: Buffer,
fee: bigint,
receivingChainID: Buffer,
) => Promise<void>;
},
) {
public addDependencies(tokenMethod: TokenMethod) {
this._tokenMethod = tokenMethod;
}

Expand Down
1 change: 0 additions & 1 deletion framework/src/modules/interoperability/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ export const getMainchainID = (chainID: Buffer): Buffer => {
return Buffer.concat([networkID, Buffer.alloc(CHAIN_ID_LENGTH - 1, 0)]);
};

// TODO: Update to use Token method after merging development
export const getTokenIDLSK = (chainID: Buffer): Buffer => {
const networkID = chainID.subarray(0, 1);
// 3 bytes for remaining chainID bytes
Expand Down
Loading

0 comments on commit 5fbae3f

Please sign in to comment.