Skip to content

Commit

Permalink
fix: pushPutBlock bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Igx22 committed Nov 17, 2024
1 parent 98bccc4 commit 0582cdb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 31 deletions.
11 changes: 11 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
#!/bin/sh

if [ -z "$DATABASE_URL" ]; then
# DATABASE_URL is needed in
# 1 migrations
# 2 prisma orm config
# 3 k8s script passes this
# for docker I pass only user/pass/host/db
DATABASE_URL="postgres://${PG_USER}:${PG_PASS}@${PG_HOST}:5432/${DB_NAME}"
export DATABASE_URL
fi


# Run Prisma migrations
npx prisma migrate deploy

Expand Down
36 changes: 15 additions & 21 deletions src/modules/archive/archive-node.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
InputJsonValue,
InputJsonObject,
} from '@prisma/client/runtime/library';
import { Tuple } from '../../utilz/tuple';

type Transaction = {
ts?: bigint | number;
Expand Down Expand Up @@ -60,20 +61,18 @@ export class ArchiveNodeService implements Consumer<QItem> {
}
}

public async handleBlock(
deserializedBlock: Block,
blockBytes: Uint8Array,
): Promise<boolean> {
public async handleBlock(blockObj: Block, blockBytes: Uint8Array): Promise<Tuple<boolean, string>> {
try {
const block = deserializedBlock.toObject();
if (!(await this.validateBlock(deserializedBlock))) {
throw new Error('Block validation failed');
}
// Extract block hash from the block
const blockHash = this.getBlockHash(block);
// check by block hash
const blockHash = BlockUtil.hashBlockAsHex(blockBytes);
if (await this.isBlockAlreadyStored(blockHash)) {
console.log('Block already exists, skipping:', blockHash);
return true;
return [true, null];
}
// check if valid
const block = blockObj.toObject();
if (!(await this.validateBlock(blockObj))) {
throw new Error('Block validation failed');
}

// Prepare the block data for insertion
Expand All @@ -83,16 +82,15 @@ export class ArchiveNodeService implements Consumer<QItem> {
data: Buffer.from(blockBytes), // Store the binary data
ts: block.ts,
};

// Prepare transaction data for insertion
const transactionsData = await this.prepareTransactionsData(
deserializedBlock.getTxobjList(),
blockObj.getTxobjList(),
blockHash,
block.ts,
);
if (transactionsData.length === 0) {
console.log('All transactions already exist, skipping block insert.');
return true;
return [true, null];
}
// Insert block into the database
await this.prisma.block.create({ data: blockData });
Expand All @@ -101,10 +99,10 @@ export class ArchiveNodeService implements Consumer<QItem> {
await this.prisma.transaction.createMany({ data: transactionsData });

console.log('Block and transactions inserted:', blockHash);
return true;
return [true, null];
} catch (error) {
console.error('Failed to process block:', error);
return false;
return [false, error.message];
}
}

Expand Down Expand Up @@ -160,11 +158,7 @@ export class ArchiveNodeService implements Consumer<QItem> {
}

// TODO: remove from or sender its redundant
private async prepareTransactionsData(
txObjList: Array<TransactionObj>,
blockHash: string,
blockTs: number,
): Promise<Transaction[]> {
private async prepareTransactionsData(txObjList: Array<TransactionObj>, blockHash: string, blockTs: number,): Promise<Transaction[]> {
const transactionsData = [];

for (const txObj of txObjList) {
Expand Down
19 changes: 15 additions & 4 deletions src/modules/block/block.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { Block, Prisma, Transaction } from '@prisma/client';
import { ArchiveNodeService } from '../archive/archive-node.service';
import { BitUtil } from '../../utilz/bitUtil';
import { BlockUtil } from '../validator/blockUtil';
import { Logger } from 'winston';
import { WinstonUtil } from '../../utilz/winstonUtil';
import { StrUtil } from '../../utilz/strUtil';

@Injectable()
export class BlockService {
private log: Logger = WinstonUtil.newLog(BlockService);

constructor(private prisma: PrismaService,
private archiveNodeService: ArchiveNodeService) {}

Expand Down Expand Up @@ -148,8 +153,9 @@ export class BlockService {
}

// TODO: Add signature validation
// TODO: normal logging
async push_putBlockHash(hashes: string[]) {
console.log('Input hashes:', hashes);
this.log.debug('push_putBlockHash: %s', StrUtil.fmt(hashes));
if (hashes.length === 0) {
return [];
}
Expand All @@ -163,13 +169,13 @@ export class BlockService {
const statusArr = results.map((result) =>
result.is_present === 1 ? 'DO_NOT_SEND' : 'SEND',
);
console.log('Returning response:', statusArr); // Debug final response
this.log.debug('Returning response: %s', statusArr);
return statusArr;
}

// TODO: add signature validation
async push_putBlock(blocks: string[]):Promise<{ status: string; reason?: string }[]> {
console.log('blocks:', blocks);
this.log.debug('push_putBlock: %s', StrUtil.fmt(blocks));
let statusArr: { status: string; reason?: string }[] = [];
if (blocks.length === 0) {
return statusArr;
Expand All @@ -180,7 +186,11 @@ export class BlockService {
let block = blocks[i];
const mb = BitUtil.base16ToBytes(block);
const parsedBlock = BlockUtil.parseBlock(mb);
const res = await this.archiveNodeService.handleBlock(parsedBlock, mb,);
const [res, err] = await this.archiveNodeService.handleBlock(parsedBlock, mb);
if(err!=null) {
statusArr.push({ status: 'REJECTED', reason: err });
continue;
}
if (!res) {
statusArr.push({ status: 'REJECTED', reason: 'duplicate' });
continue;
Expand All @@ -190,6 +200,7 @@ export class BlockService {
statusArr.push({ status: 'REJECTED', reason: error.message });
}
}
this.log.debug('Returning response: %s', statusArr);
return statusArr;
}
}
21 changes: 15 additions & 6 deletions src/modules/validator/validator-contract-state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export class ValidatorContractState implements OnModuleInit {
return this.contractCli.snodes
}

public getArchivalNodesMap(): Map<string, NodeInfo> {
return this.contractCli.anodes
}

public getActiveValidatorsExceptSelf(): NodeInfo[] {
const allNodes = Array.from(this.getAllNodesMap().values())
const onlyGoodValidators = allNodes.filter(
Expand Down Expand Up @@ -138,10 +142,12 @@ class ContractClientFactory {
private pushTokenAddr: string
private validatorRpcEndpoint: string
private validatorRpcNetwork: number
private abiDir: string
private configDir: string
nodeWallet: Wallet
// private nodeWallet: Signer;
private validatorPrivateKeyFile: string
private validatorEthKeyPath: string; // new
private validatorPrivateKeyFileName: string; // old
private validatorPrivateKeyPass: string
private nodeAddress: string

Expand All @@ -154,12 +160,13 @@ class ContractClientFactory {
this.validatorRpcEndpoint,
this.validatorRpcNetwork
)
this.configDir = EnvLoader.getPropertyOrFail('CONFIG_DIR')
this.abi = ContractClientFactory.loadValidatorContractAbi(this.configDir, 'ValidatorV1.json')
this.configDir = EnvLoader.getPropertyOrFail('CONFIG_DIR');
this.abiDir = EnvLoader.getPropertyOrDefault('ABI_DIR', this.configDir + "/abi");
this.abi = ContractClientFactory.loadValidatorContractAbi(this.abiDir, './ValidatorV1.json')
}

private static loadValidatorContractAbi(configDir: string, fileNameInConfigDir: string): string {
const fileAbsolute = path.resolve(configDir, `./${fileNameInConfigDir}`)
const fileAbsolute = path.resolve(configDir, `${fileNameInConfigDir}`)
const file = fs.readFileSync(fileAbsolute, 'utf8')
const json = JSON.parse(file)
const abi = json.abi
Expand All @@ -175,10 +182,12 @@ class ContractClientFactory {

// creates a client, using an encrypted private key from disk, so that we could write to the blockchain
public async buildRWClient(log: Logger): Promise<ValidatorCtClient> {
this.validatorPrivateKeyFile = EnvLoader.getPropertyOrFail('VALIDATOR_PRIVATE_KEY_FILE')
this.validatorPrivateKeyFileName = EnvLoader.getPropertyOrFail('VALIDATOR_PRIVATE_KEY_FILE')
this.validatorPrivateKeyPass = EnvLoader.getPropertyOrFail('VALIDATOR_PRIVATE_KEY_PASS')

const jsonFile = readFileSync(this.configDir + '/' + this.validatorPrivateKeyFile, 'utf-8')
// this is a new variable, which fallbacks to old
this.validatorEthKeyPath = EnvLoader.getPropertyOrDefault('ETH_KEY_PATH', this.configDir + '/' + this.validatorPrivateKeyFileName);
const jsonFile = readFileSync(this.validatorEthKeyPath, {encoding: 'utf8', flag: 'r'})
this.nodeWallet = await Wallet.fromEncryptedJson(jsonFile, this.validatorPrivateKeyPass)
this.nodeAddress = await this.nodeWallet.getAddress()

Expand Down

0 comments on commit 0582cdb

Please sign in to comment.