use of org.apache.tuweni.bytes.Bytes32 in project xdagj by XDagger.
the class XdagPow method onNewShare.
protected void onNewShare(XdagField shareInfo, MinerChannel channel) {
try {
Bytes32 hash;
// if randomx fork
if (kernel.getRandomXUtils().isRandomxFork(currentTask.getTaskTime())) {
MutableBytes taskData = MutableBytes.create(64);
// currentTask.getTask()[0].getData().copyTo(taskData, 0);
taskData.set(0, currentTask.getTask()[0].getData());
// shareInfo.getData().reverse().copyTo(taskData, 32);
taskData.set(32, shareInfo.getData().reverse());
hash = Bytes32.wrap(kernel.getRandomXUtils().randomXPoolCalcHash(taskData, taskData.size(), currentTask.getTaskTime()).reverse());
} else {
XdagSha256Digest digest = new XdagSha256Digest(currentTask.getDigest());
// hash = Bytes32.wrap(digest.sha256Final(Arrays.reverse(shareInfo.getData().toArray())));
hash = Bytes32.wrap(digest.sha256Final(shareInfo.getData().reverse()));
}
if (compareTo(hash.toArray(), 0, 32, minHash.toArray(), 0, 32) < 0) {
minHash = hash;
minShare = Bytes32.wrap(shareInfo.getData().reverse());
// put minshare into nonce
generateBlock.setNonce(minShare);
// myron
int index = (int) ((currentTask.getTaskTime() >> 16) & kernel.getConfig().getPoolSpec().getAwardEpoch());
// int index = (int) ((currentTask.getTaskTime() >> 16) & 7);
minShares.set(index, minShare);
blockHashs.set(index, generateBlock.recalcHash());
log.debug("New MinHash :" + minHash.toHexString());
log.debug("New MinShare :" + minShare.toHexString());
}
// update miner state
MinerCalculate.updateMeanLogDiff(channel, currentTask, hash);
MinerCalculate.calculateNopaidShares(kernel.getConfig(), channel, hash, currentTask.getTaskTime());
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
use of org.apache.tuweni.bytes.Bytes32 in project xdagj by XDagger.
the class XdagPow method createTaskByRandomXBlock.
/**
* 创建RandomX的任务
*/
private Task createTaskByRandomXBlock(Block block, long sendTime) {
Task newTask = new Task();
XdagField[] task = new XdagField[2];
RandomXMemory memory = randomXUtils.getGlobalMemory()[(int) randomXUtils.getRandomXPoolMemIndex() & 1];
// Bytes32 rxHash = Hash.sha256(Bytes.wrap(BytesUtils.subArray(block.getXdagBlock().getData(),0,480)));
Bytes32 rxHash = Hash.sha256(block.getXdagBlock().getData().slice(0, 480));
// todo
task[0] = new XdagField(rxHash.mutableCopy());
task[1] = new XdagField(MutableBytes.wrap(memory.getSeed()));
newTask.setTask(task);
newTask.setTaskTime(XdagTime.getEpoch(sendTime));
newTask.setTaskIndex(taskIndex);
return newTask;
}
use of org.apache.tuweni.bytes.Bytes32 in project xdagj by XDagger.
the class Block method toBytes.
public byte[] toBytes() {
SimpleEncoder encoder = new SimpleEncoder();
encoder.write(getEncodedBody());
for (SECP256K1.Signature sig : insigs.keySet()) {
encoder.writeSignature(BytesUtils.subArray(sig.bytes().toArray(), 0, 64));
}
if (outsig != null) {
encoder.writeSignature(BytesUtils.subArray(outsig.bytes().toArray(), 0, 64));
}
int length = encoder.getWriteFieldIndex();
tempLength = length;
int res;
if (length == 16) {
return encoder.toBytes();
}
res = 15 - length;
for (int i = 0; i < res; i++) {
encoder.writeField(new byte[32]);
}
Bytes32 nonceNotNull = Objects.requireNonNullElse(nonce, Bytes32.ZERO);
encoder.writeField(nonceNotNull.toArray());
return encoder.toBytes();
}
use of org.apache.tuweni.bytes.Bytes32 in project xdagj by XDagger.
the class AwardManagerImpl method payMiners.
/**
* @param time 时间段
* @return 错误代码 -1 没有矿工参与挖矿 不进行支付操作 -2 找不到对应的区块hash 或者 结果nonce -3 找不到对应的区块
* -4区块余额不足,不是主块不进行支付 -5 余额分配失败 -6 找不到签名密钥 -7 难度太小 不予支付
*/
public int payMiners(long time) {
log.debug("=========== start payMiners for time [{}]===========", time);
// 获取到的是当前任务的对应的+1的位置 以此延迟16轮
int index = (int) (((time >> 16) + 1) & config.getPoolSpec().getAwardEpoch());
int keyPos = -1;
int minerCounts = 0;
PayData payData = new PayData();
// 每一个区块最多可以放多少交易 这个要由密钥的位置来决定
int payminersPerBlock;
miners = new ArrayList<>();
// 统计矿工的数量
if (minerManager != null) {
for (Miner miner : minerManager.getActivateMiners().values()) {
miners.add(miner);
minerCounts++;
log.debug("矿工的数量为[{}]", minerCounts);
// log.debug("添加的矿工地址为[{}],共计[{}]个矿工",Hex.toHexString(miner.getAddressHash()), minerCounts);
}
}
// 没有矿工挖矿,直接全部收入交由地址块
if (minerCounts <= 0) {
log.debug("no miners");
return -1;
}
// 获取到要计算的hash 和对应的nocne
Bytes32 hash = blockHashs.get(index) == null ? null : blockHashs.get(index);
Bytes32 nonce = minShares.get(index) == null ? null : minShares.get(index);
if (hash == null || nonce == null) {
log.debug("can not find the hash or nonce ,hash is null?[{}],nonce is null ?[{}]", hash == null, nonce == null);
return -2;
}
// 获取到这个区块 查询时要把前面的置0
MutableBytes32 hashlow = MutableBytes32.create();
// Bytes32.wrap(BytesUtils.fixBytes(hash, 8, 24));
hashlow.set(8, Bytes.wrap(hash).slice(8, 24));
Block block = blockchain.getBlockByHash(hashlow, false);
// TODO
log.debug("Hash low : " + hashlow.toHexString());
if (keyPos < 0) {
if (kernel.getBlockchain().getMemOurBlocks().get(new ByteArrayWrapper(hashlow.toArray())) == null) {
keyPos = kernel.getBlockStore().getKeyIndexByHash(hashlow);
} else {
keyPos = kernel.getBlockchain().getMemOurBlocks().get(new ByteArrayWrapper(hashlow.toArray()));
}
log.debug("keypos : " + keyPos);
if (keyPos < 0) {
return -2;
}
}
if (block == null) {
log.debug("can't find the block");
return -3;
}
payData.balance = block.getInfo().getAmount();
if (payData.balance <= 0) {
log.debug("no main block,can't pay");
return -4;
}
// 计算矿池部分的收益
payData.poolFee = BigDecimalUtils.mul(payData.balance, poolRation);
payData.unusedBalance = payData.balance - payData.poolFee;
// 进行各部分奖励的计算
if (payData.unusedBalance <= 0) {
log.debug("Balance no enough");
return -5;
}
if (keyPos < 0) {
log.debug("can't find the key");
return -6;
}
// todo 这里不够严谨把 如果时第三把第四把呢
if (wallet.getAccounts().size() - 1 == keyPos) {
payminersPerBlock = 11;
} else {
payminersPerBlock = 9;
}
// poolMiner.setDiffSum(time, 0.0);
// poolMiner.setPrevDiffSum(time, minerCounts);
// 真正处理的数据是在这一块
// 这个函数会把每一个矿工的计算出来的diff 和prevdiff 都存在上面的列表
// prevDiffSum 是每一个矿工的本轮计算的难度 加上以前所有难度之和
// diffs 是本轮进行的计算
// 同样开辟两个数组
diff = new ArrayList<>(minerCounts);
prev_diff = new ArrayList<>(minerCounts);
Collections.fill(diff, 0.0);
Collections.fill(prev_diff, 0.0);
double prevDiffSum = precalculatePayments(nonce, index, payData);
log.debug("after cal prevdiffSum为[{}]", prevDiffSum);
if (prevDiffSum <= DBL) {
log.debug("diff is too low");
return -7;
}
// 通过precalculatePay后计算出的数据 进行计算
doPayments(hashlow, payminersPerBlock, payData, keyPos);
log.debug("=========== end payMiners for time [{}]===========", time);
return 0;
}
use of org.apache.tuweni.bytes.Bytes32 in project xdagj by XDagger.
the class Block method verifiedKeys.
/**
* 只匹配输入签名 并返回有用的key
*/
public List<SECP256K1.PublicKey> verifiedKeys() {
List<SECP256K1.PublicKey> keys = getPubKeys();
List<SECP256K1.PublicKey> res = new ArrayList<>();
Bytes digest;
Bytes32 hash;
for (SECP256K1.Signature sig : this.getInsigs().keySet()) {
digest = getSubRawData(this.getInsigs().get(sig) - 1);
for (SECP256K1.PublicKey publicKey : keys) {
// TODO: paulochen 是不是可以替换
byte[] pubkeyBytes = publicKey.asEcPoint().getEncoded(true);
hash = Hash.hashTwice(Bytes.wrap(digest, Bytes.wrap(pubkeyBytes)));
if (SECP256K1.verifyHashed(hash, sig, publicKey)) {
res.add(publicKey);
}
}
}
digest = getSubRawData(getOutsigIndex() - 2);
for (SECP256K1.PublicKey publicKey : keys) {
// TODO: paulochen 是不是可以替换
byte[] pubkeyBytes = publicKey.asEcPoint().getEncoded(true);
hash = Hash.hashTwice(Bytes.wrap(digest, Bytes.wrap(pubkeyBytes)));
if (SECP256K1.verifyHashed(hash, this.getOutsig(), publicKey)) {
res.add(publicKey);
}
}
return res;
}
Aggregations