Skip to content

Commit

Permalink
feat: replace completTransfer with batch way
Browse files Browse the repository at this point in the history
  • Loading branch information
dadiorchen committed Feb 25, 2021
1 parent 13bd552 commit d08092d
Show file tree
Hide file tree
Showing 8 changed files with 1,463 additions and 15 deletions.
1,366 changes: 1,366 additions & 0 deletions '

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions server/models/Token.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const TransactionRepository = require("../repositories/TransactionRepository");
const HttpError = require("../utils/HttpError");
const { validate: uuidValidate } = require('uuid');
const Joi = require("joi");
const expect = require("expect-runtime");

class Token{

Expand Down Expand Up @@ -55,6 +56,10 @@ class Token{
transfer_pending_id: null,
wallet_id: transfer.destination_wallet_id,
});
expect(transfer).match({
source_wallet_id: expect.any(String),
destination_wallet_id: expect.any(String),
});
await this.transactionRepository.create({
token_id: this._id,
transfer_id: transfer.id,
Expand Down
19 changes: 7 additions & 12 deletions server/models/Wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,9 +489,7 @@ class Wallet{
},
});
log.debug("now, deal with tokens");
for(let token of tokens){
await token.completeTransfer(transfer);
}
await this.tokenService.completeTransfer(tokens, transfer);
return transfer;

}else{
Expand Down Expand Up @@ -569,9 +567,7 @@ class Wallet{
});
log.debug("now, deal with tokens");
const tokens = await this.tokenService.getTokensByBundle(sender, bundleSize)
for(let token of tokens){
await token.completeTransfer(transfer);
}
await this.tokenService.completeTransfer(tokens, transfer);
return transfer;
}else{
if(hasControlOverSender){
Expand Down Expand Up @@ -692,15 +688,14 @@ class Wallet{
if(tokens.length < transfer.parameters.bundle.bundleSize){
throw new HttpError(403, "Do not have enough tokens");
}
for(let token of tokens){
await token.completeTransfer(transfer);
}
await this.tokenService.completeTransfer(tokens, transfer);
}else{
log.debug("transfer tokens");
const tokens = await this.tokenService.getTokensByPendingTransferId(transferId);
for(let token of tokens){
await token.completeTransfer(transfer);
}
expect(transfer).match({
source_wallet_id: expect.any(String),
});
await this.tokenService.completeTransfer(tokens, transfer);
}
return transferJson;
}
Expand Down
10 changes: 7 additions & 3 deletions server/models/Wallet.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ describe("Wallet", () => {
const fn1 = sinon.stub(Wallet.prototype, "hasTrust").resolves(true);
sinon.stub(Wallet.prototype, "isDeduct").resolves(false);
const fn2 = sinon.stub(TransferRepository.prototype, "create");
const fn3 = sinon.stub(Token.prototype, "completeTransfer");
const fn3 = sinon.stub(TokenService.prototype, "completeTransfer");
sinon.stub(Wallet.prototype, "hasControlOver").resolves(true);
const fn4 = sinon.stub(TokenService.prototype, "getTokensByBundle").resolves([
new Token(uuid.v4(), session)
Expand Down Expand Up @@ -535,13 +535,17 @@ describe("Wallet", () => {
});

it("acceptTransfer", async () => {
const walletId1 = uuid.v4();
const walletId2 = uuid.v4();
const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({
id: transferId,
state: Transfer.STATE.pending,
source_wallet_id: walletId1,
destination_wallet_id: walletId2,
});
const fn2 = sinon.stub(TransferRepository.prototype, "update");
const fn3 = sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([ token ]);
const fn4 = sinon.stub(Token.prototype, "completeTransfer");
const fn4 = sinon.stub(TokenService.prototype, "completeTransfer");
const fn5 = sinon.stub(WalletService.prototype, "getById");
const fn6 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true);
await wallet.acceptTransfer(transferId);
Expand Down Expand Up @@ -569,7 +573,7 @@ describe("Wallet", () => {
},
});
const fn2 = sinon.stub(TransferRepository.prototype, "update");
const fn4 = sinon.stub(Token.prototype, "completeTransfer");
const fn4 = sinon.stub(TokenService.prototype, "completeTransfer");
const fn5 = sinon.stub(TokenService.prototype, "getTokensByBundle").resolves([ token ]);
const fn6 = sinon.stub(WalletService.prototype, "getById");
const fn7 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true);
Expand Down
21 changes: 21 additions & 0 deletions server/repositories/BaseRepository.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Session = require("../models/Session");
const expect = require("expect-runtime");
const HttpError = require("../utils/HttpError");
const log = require("loglevel");

class BaseRepository{

Expand Down Expand Up @@ -80,6 +81,16 @@ class BaseRepository{
return result[0];
}

/*
* update all rows matching given id
*/
async updateByIds(object, ids){
let objectCopy = {}
Object.assign(objectCopy, object)
delete objectCopy.id
const result = await this._session.getDB()(this._tableName).update(objectCopy).whereIn("id", ids);
}

async create(object){
const result = await this._session.getDB()(this._tableName).insert(object).returning("*");
expect(result).match([{
Expand All @@ -88,6 +99,16 @@ class BaseRepository{
return result[0];
}

/*
* return ids created
*/
async batchCreate(objects){
log.warn("object batch:", objects);
const result = await this._session.getDB().batchInsert(this._tableName,objects).returning('id');
expect(result).match([expect.any(String)]);
return result;
}

}

module.exports = BaseRepository;
24 changes: 24 additions & 0 deletions server/repositories/BaseRepository.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,28 @@ describe("BaseRepository", () => {
describe.skip("count support and and or", () => {
});
});

it("updateByIds", async () => {
tracker.uninstall();
tracker.install();
tracker.on("query", (query) => {
expect(query.sql).match(/update.*where.*in/is);
query.response([{
count: "1",
}]);
});
await baseRepository.updateByIds({
column: "testColumn",
}, [1]);
});

it("batchCreate", async () => {
tracker.uninstall();
tracker.install();
tracker.on("query", (query) => {
expect(query.sql).match(/(BEGIN|ROLLBACK|COMMIT|insert)/is);
query.response(["id"]);
});
await baseRepository.batchCreate([{a:"a", b:"b"},{a:"a",b:"b"}]);
});
});
21 changes: 21 additions & 0 deletions server/services/TokenService.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Token = require("../models/Token");
const TokenRepository = require("../repositories/TokenRepository");
const TransactionRepository = require("../repositories/TransactionRepository");
const log = require("loglevel");

class TokenService{

Expand Down Expand Up @@ -96,6 +97,26 @@ class TokenService{
return tokens;
}

/*
* To replace token.completeTransfer, as a bulk operaction
*/
async completeTransfer(tokens, transfer){
log.debug("Token complete transfer batch");
await this.tokenRepository.updateByIds({
transfer_pending: false,
transfer_pending_id: null,
wallet_id: transfer.destination_wallet_id,
},
tokens.map(token => token.getId()),
);
await this.transactionRepository.batchCreate(tokens.map(token => ({
token_id: token.getId(),
transfer_id: transfer.id,
source_wallet_id: transfer.source_wallet_id,
destination_wallet_id: transfer.destination_wallet_id,
})));
}

}

module.exports = TokenService;
12 changes: 12 additions & 0 deletions server/services/TokenService.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,17 @@ describe("Token", () => {
});
});

it("completeTransfer", async () => {
const tokenId1 = uuid.v4();
const transferId1 = uuid.v4();
const token1 = new Token({id:tokenId1});
const updateByIds = sinon.stub(TokenRepository.prototype, "updateByIds");
const batchCreate = sinon.stub(TransactionRepository.prototype, "batchCreate");
const transfer = {
destination_wallet_id: transferId1,
}
const tokens = await tokenService.completeTransfer([token1], transfer);
expect(updateByIds).calledWith(sinon.match({wallet_id:transferId1}), [tokenId1]);
});

});

0 comments on commit d08092d

Please sign in to comment.