mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
writing TransactionTransfer Validation method, update tests
This commit is contained in:
parent
da84873379
commit
18848f65ae
@ -49,7 +49,7 @@ class StateErrorsController extends AppController
|
||||
}
|
||||
|
||||
$errors = $this->StateErrors->find('all')->where(['state_user_id' => $user['id']])->contain(false);
|
||||
$transactionTypes = $this->StateErrors->TransactionTypes->find('all')->select(['id', 'name', 'text']);
|
||||
$transactionTypes = $this->StateErrors->TransactionTypes->find('all')->select(['id', 'name', 'text'])->order(['id']);
|
||||
|
||||
$this->set('errors', $errors);
|
||||
$this->set('transactionTypes', $transactionTypes->toList());
|
||||
|
||||
@ -3,11 +3,10 @@
|
||||
namespace Model\Transactions;
|
||||
|
||||
//use App\Model\Transactions\TransactionBase;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
class TransactionTransfer extends TransactionBase {
|
||||
private $protoTransactionTransfer;
|
||||
private $receiver_pubkey_hex;
|
||||
private $sender_pubkey_hex;
|
||||
|
||||
public function __construct($protoTransactionTransfer) {
|
||||
$this->protoTransactionTransfer = $protoTransactionTransfer;
|
||||
@ -50,9 +49,107 @@ class TransactionTransfer extends TransactionBase {
|
||||
}
|
||||
|
||||
public function validate($sigPairs) {
|
||||
$this->addError('TransactionTransfer::validate', 'not implemented yet');
|
||||
return false;
|
||||
//return true;
|
||||
//$this->addError('TransactionTransfer::validate', 'not implemented yet');
|
||||
//return false;
|
||||
//$time = microtime(true);
|
||||
static $functionName = 'TransactionCreation::validate';
|
||||
/*
|
||||
* // check signature(s)
|
||||
foreach($sigPairs as $sigPair) {
|
||||
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
|
||||
$pubkey = $sigPair->getPubKey();
|
||||
$signature = $sigPair->getEd25519();
|
||||
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
|
||||
$this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
$sigPubHexs = [];
|
||||
foreach($sigPairs as $sigPair) {
|
||||
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
|
||||
$pubkey = bin2hex($sigPair->getPubKey());
|
||||
$hash = TransactionCreation::DRMakeStringHash($pubkey);
|
||||
if(!isset($sigPubHexs[$hash])) {
|
||||
$sigPubHexs[$hash] = [$pubkey];
|
||||
} else {
|
||||
array_push($sigPubHexs[$hash], $pubkey);
|
||||
}
|
||||
//array_push($sigPubHexs, $pubkey);
|
||||
}
|
||||
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
|
||||
$senderAmounts = $this->protoTransactionTransfer->getSenderAmounts();
|
||||
$senderSum = 0;
|
||||
$receiverSum = 0;
|
||||
|
||||
$senderPublics = [];
|
||||
foreach($senderAmounts as $i => $senderAmount) {
|
||||
$senderPublic = $senderAmount->getEd25519SenderPubkey();
|
||||
$senderPublicHex = bin2hex($senderPublic);
|
||||
array_push($senderPublics, $senderPublic);
|
||||
|
||||
if(strlen($senderPublicHex) != 64) {
|
||||
$this->addError($functionName, 'invalid sender public key');
|
||||
return false;
|
||||
}
|
||||
// check if signature exist for sender
|
||||
$hash = TransactionCreation::DRMakeStringHash($senderPublicHex);
|
||||
if(!isset($sigPubHexs[$hash]) || in_array($senderPublicHex, $sigPubHexs[$hash]) === FALSE) {
|
||||
$this->addError($functionName, 'missing signature for sender');
|
||||
return false;
|
||||
}
|
||||
// check if sender has enough Gradido
|
||||
$amount = $senderAmount->getAmount();
|
||||
$user = $stateUsersTable
|
||||
->find('all')
|
||||
->select(['id'])
|
||||
->where(['public_key' => $senderPublic])
|
||||
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]])->first();
|
||||
if(!$user) {
|
||||
$this->addError($functionName, 'couldn\'t find sender ' . $i .' in db' );
|
||||
return false;
|
||||
}
|
||||
//var_dump($user);
|
||||
if(intval($user->state_balances[0]->amount) < intval($amount)) {
|
||||
$this->addError($functionName, 'sender ' . $i . ' hasn\t enough GDD');
|
||||
return false;
|
||||
}
|
||||
$senderSum += $amount;
|
||||
}
|
||||
$uniqueSenderPublics = array_unique($senderPublics);
|
||||
if(count($senderPublics) !== count($uniqueSenderPublics)) {
|
||||
$this->addError($functionName, 'duplicate sender public key');
|
||||
return false;
|
||||
}
|
||||
|
||||
$receiverAmounts = $this->protoTransactionTransfer->getReceiverAmounts();
|
||||
$receiverPublics = [];
|
||||
foreach($receiverAmounts as $reveiverAmount) {
|
||||
if(strlen($reveiverAmount->getEd25519ReceiverPubkey()) != 32) {
|
||||
$this->addError($functionName, 'invalid receiver public key');
|
||||
return false;
|
||||
}
|
||||
array_push($receiverPublics, $reveiverAmount->getEd25519ReceiverPubkey());
|
||||
$receiverSum += $reveiverAmount->getAmount();
|
||||
}
|
||||
$uniqueReceiverPublic = array_unique($receiverPublics);
|
||||
if(count($uniqueReceiverPublic) !== count($receiverPublics)) {
|
||||
$this->addError($functionName, 'duplicate receiver public key');
|
||||
return false;
|
||||
}
|
||||
$uniquePublics = array_unique(array_merge($receiverPublics, $senderPublics));
|
||||
if(count($uniquePublics) !== count($senderPublics) + count($receiverPublics)) {
|
||||
// means at least one sender is the same as one receiver
|
||||
$this->addError($functionName, 'duplicate public in sender and receiver');
|
||||
return false;
|
||||
}
|
||||
if($senderSum !== $receiverSum) {
|
||||
$this->addError($functionName, 'sender amount doesn\'t match receiver amount');
|
||||
return false;
|
||||
}
|
||||
//die("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save($transaction_id, $firstPublic) {
|
||||
|
||||
@ -21,11 +21,25 @@ $this->assign('title', __('Fehlermeldungen'));
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($errors as $error) :
|
||||
$type = $transactionTypes[$error->transaction_type_id]; ?>
|
||||
$type = $transactionTypes[$error->transaction_type_id-1];
|
||||
$errorMessage = "";
|
||||
$errorArray = json_decode($error->message_json, true);
|
||||
if(isset($errorArray['details'])) {
|
||||
|
||||
foreach($errorArray['details'][0] as $function => $errorString) {
|
||||
$errorMessage = '<b>' . $function . '</b><br> ' . $errorString;
|
||||
}
|
||||
|
||||
} else {
|
||||
$errorMessage = $error->message_json;
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td title="<?= $type->text ?>"><?= $type->name ?></td>
|
||||
<td><?= $error->created ?></td>
|
||||
<td><?= $error->message_json ?></td>
|
||||
<td><?= $errorMessage ?></td>
|
||||
<td><?= $this->Html->link(__('Delete'), ['action' => 'deleteForUser', $error->id], ['class' => 'grd-form-bn grd-form-bn-discard']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@ -42,6 +42,12 @@ class StateBalancesFixture extends TestFixture
|
||||
'modified' => '2019-11-05 18:02:28',
|
||||
'amount' => 1200
|
||||
],
|
||||
[
|
||||
'id' => 10,
|
||||
'state_user_id' => 4,
|
||||
'modified' => '2019-11-11 14:58:54',
|
||||
'amount' => 1200000
|
||||
]
|
||||
];
|
||||
parent::init();
|
||||
}
|
||||
|
||||
@ -49,6 +49,15 @@ class StateUsersFixture extends TestFixture
|
||||
'first_name' => 'Dario',
|
||||
'last_name' => 'Rekowski'
|
||||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'index_id' => 0,
|
||||
'group_id' => 0,
|
||||
'public_key' => hex2bin('8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d'),
|
||||
'email' => 'dariofrodo@gmx.de',
|
||||
'first_name' => 'Dario',
|
||||
'last_name' => 'Frodo'
|
||||
],
|
||||
[
|
||||
'id' => 11,
|
||||
'index_id' => 0,
|
||||
|
||||
@ -23,6 +23,7 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
|
||||
'app.TransactionCreations',
|
||||
'app.Transactions',
|
||||
'app.StateUsers',
|
||||
'app.StateErrors',
|
||||
'app.TransactionSignatures',
|
||||
'app.TransactionSendCoins',
|
||||
'app.StateBalances',
|
||||
@ -33,7 +34,8 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
|
||||
'validCreation' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQJ8wF12eZo3hcMAlAKKJ9WLT-zuSkNmGh7D98UEqH4KoIysnCkXqEya9EBZl9o11_nJ8xmm_nOevuVjR-GfLMQ8qSQoOSGFsbG8gV2VsdCAxMjMSBgiZm4ruBUovCicKIJSuE1uTzZ8zdStOVcQZA6P6oTp1u5C_1BHqHUoaXnEfEKDakwEQtYntlgo',
|
||||
'validCreation900' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQNVZ8Ae3Zbg3G0wZ840fzKan6N4KtTcSe0KYi17kQwFmsl18oFxXv8_s6j1xXFrIKjy1_1Olq0a7xYLErDMkjwYqORIGCNb5iu4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgNHKCBC1ie2WCg',
|
||||
'validCreation1200' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQEEey5QMAdldoOTP_jTETHgOQriGsixEY0cziQeRfT_J5YtbI_A6AizEYD-JcxmRmXzv1xjjTgsV39Y32ta2CQkqORIGCIeGi-4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgOy4CxC1ie2WCg',
|
||||
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3'
|
||||
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3',
|
||||
'validTransfer' => 'GmYKZAoggZC9pYXuXx2fv30G6B5p7BjhM3YQTP9Ut0V-t9PvcQ0SQDddHyKzAX3LBV0PuDiPc6lxkUipss5tyuLRpMtFJQnT30tsbYIkA1FXimjMKOoiuLswf4OLLV3bAIYehW-b9AgqYQoFSGFsbG8SBgiJlaPvBUJQCiYKIIGQvaWF7l8dn799BugeaewY4TN2EEz_VLdFfrfT73ENEICfSRImCiDtdleSLxhUgEbMW9DpqIwsykFj3-z_enKEOuGnXrmW8xCAn0k'
|
||||
];
|
||||
|
||||
/*public function setUp() {
|
||||
@ -125,6 +127,14 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testValidTransfer()
|
||||
{
|
||||
$this->postAndParse(
|
||||
['method' => 'putTransaction', 'transaction' => $this->transactions['validTransfer']],
|
||||
['state' => 'success']
|
||||
);
|
||||
}
|
||||
|
||||
/*public function testMissingPreviousTransaction()
|
||||
{
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user