Merge pull request #17 from k1rill-fedoseev/msg-compressing

Msg compressing
This commit is contained in:
Kirill Fedoseev 2019-08-25 16:13:45 +03:00 committed by GitHub
commit 46094c6ae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 413 additions and 22 deletions

4
.gitignore vendored
View File

@ -8,8 +8,8 @@ data/
demo/validator*/db
demo/validator*/keys
demo/validator*/queue
demo/ganache_home
demo/ganache_side
demo/ganache_home_db/
demo/ganache_side_db/
src/deploy/deploy-home/build/
src/deploy/deploy-side/build/
src/deploy/deploy-test/build/

View File

@ -6,27 +6,27 @@ cd $(dirname "$0")
echo "Starting side test blockchain"
mntpoint=`pwd`/ganache_side_db
if [ ! -d ${mntpoint} ]; then
mkdir ${mntpoint}
mntpoint="$(pwd)/ganache_side_db"
if [ ! -d "$mntpoint" ]; then
mkdir "$mntpoint"
fi
docker kill ganache_side > /dev/null 2>&1 || true
docker network create blockchain_side > /dev/null 2>&1 || true
docker run -d --network blockchain_side --rm --name ganache_side -v ${mntpoint}:/app/db \
docker run -d --network blockchain_side --rm --name ganache_side -v "$mntpoint:/app/db" \
trufflesuite/ganache-cli:latest \
-m "shrug dwarf easily blade trigger lucky reopen cage lake scatter desk boat" -i 33 -q --db /app/db
echo "Starting home test blockchain"
mntpoint=`pwd`/ganache_home_db
if [ ! -d ${mntpoint} ]; then
mkdir ${mntpoint}
mntpoint="$(pwd)/ganache_home_db"
if [ ! -d "$mntpoint" ]; then
mkdir "$mntpoint"
fi
docker kill ganache_home > /dev/null 2>&1 || true
docker network create blockchain_home > /dev/null 2>&1 || true
docker run -d --network blockchain_home --rm --name ganache_home -v ${mntpoint}:/app/db \
docker run -d --network blockchain_home --rm --name ganache_home -v "$mntpoint:/app/db" \
trufflesuite/ganache-cli:latest \
-m "shrug dwarf easily blade trigger lucky reopen cage lake scatter desk boat" -i 44 -q --db /app/db

View File

@ -6,6 +6,6 @@ COPY package.json /proxy/
RUN npm install
COPY index.js /proxy/
COPY index.js encode.js decode.js /proxy/
ENTRYPOINT ["node", "index.js"]

230
src/oracle/proxy/decode.js Normal file
View File

@ -0,0 +1,230 @@
const BN = require('bn.js')
function Tokenizer (_buffer) {
const buffer = _buffer
let position = 0
return {
isEmpty: function () {
return position === buffer.length
},
parse: function (length = 32, base = 16) {
const res = new BN(buffer.slice(position, position + length)).toString(base)
position += length
return res
},
byte: function () {
return buffer[position++]
}
}
}
const keygenDecoders = [
null,
// round 1
function (tokenizer) {
const res = {
e: {
n: tokenizer.parse(256, 10)
},
com: tokenizer.parse(),
correct_key_proof: {
sigma_vec: []
}
}
while (!tokenizer.isEmpty()) {
res.correct_key_proof.sigma_vec.push(tokenizer.parse(256, 10))
}
return res
},
// round 2
function (tokenizer) {
return {
blind_factor: tokenizer.parse(),
y_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
}
}
},
// round 3
function (tokenizer) {
const res = {
ciphertext: [],
tag: []
}
for (let i = 0; i < 32; i++) {
res.ciphertext.push(tokenizer.byte())
}
for (let i = 0; i < 16; i++) {
res.tag.push(tokenizer.byte())
}
return res
},
// round 4
function (tokenizer) {
const res = {
parameters: {
threshold: tokenizer.byte(),
share_count: tokenizer.byte()
},
commitments: []
}
while (!tokenizer.isEmpty()) {
res.commitments.push({
x: tokenizer.parse(),
y: tokenizer.parse(),
})
}
return res
},
// round 5
function (tokenizer) {
return {
pk: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
pk_t_rand_commitment: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
challenge_response: tokenizer.parse()
}
}
]
const signDecoders = [
// round 0
function (tokenizer) {
return tokenizer.byte()
},
// round 1
function (tokenizer) {
return [
{
com: tokenizer.parse()
},
{
c: tokenizer.parse(512)
}
]
},
// round 2
function (tokenizer) {
const res = []
for (let i = 0; i < 2; i++) {
res[i] = {
c: tokenizer.parse(512),
b_proof: {
pk: {
x: tokenizer.parse(),
y: tokenizer.parse(),
},
pk_t_rand_commitment: {
x: tokenizer.parse(),
y: tokenizer.parse(),
},
challenge_response: tokenizer.parse(),
},
beta_tag_proof: {
pk: {
x: tokenizer.parse(),
y: tokenizer.parse(),
},
pk_t_rand_commitment: {
x: tokenizer.parse(),
y: tokenizer.parse(),
},
challenge_response: tokenizer.parse(),
}
}
}
return res
},
// round 3
function (tokenizer) {
return tokenizer.parse()
},
// round 4
function (tokenizer) {
return {
blind_factor: tokenizer.parse(),
g_gamma_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
}
}
},
// round 5
function (tokenizer) {
return {
com: tokenizer.parse()
}
},
// round 6
function (tokenizer) {
return [
{
V_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
A_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
B_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
blind_factor: tokenizer.parse()
},
{
T: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
A3: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
z1: tokenizer.parse(),
z2: tokenizer.parse()
}
]
},
// round 7
function (tokenizer) {
return {
com: tokenizer.parse()
}
},
// round 8
function (tokenizer) {
return {
u_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
t_i: {
x: tokenizer.parse(),
y: tokenizer.parse()
},
blind_factor: tokenizer.parse()
}
},
// round 9
function (tokenizer) {
return tokenizer.parse()
},
]
module.exports = function (isKeygen, round, value) {
value = Buffer.from(value.substr(2), 'hex')
const tokenizer = Tokenizer(value)
const roundNumber = parseInt(round[round.length - 1])
const decoder = (isKeygen ? keygenDecoders : signDecoders)[roundNumber]
const decoded = JSON.stringify(decoder(tokenizer))
console.log(decoded)
return decoded
}

147
src/oracle/proxy/encode.js Normal file
View File

@ -0,0 +1,147 @@
const BN = require('bignumber.js')
function padZeros (s, len) {
while (s.length < len)
s = '0' + s
return s
}
function makeBuffer (value, length = 32, base = 16) {
return Buffer.from(padZeros(new BN(value, base).toString(16), length * 2), 'hex')
}
const keygenEncoders = [
null,
// round 1
function * (value) {
yield makeBuffer(value.e.n, 256, 10)
yield makeBuffer(value.com)
for (let x of value.correct_key_proof.sigma_vec) {
yield makeBuffer(x, 256, 10)
}
},
// round 2
function * (value) {
yield makeBuffer(value.blind_factor)
yield makeBuffer(value.y_i.x)
yield makeBuffer(value.y_i.y)
},
// round 3
function * (value) {
yield Buffer.from(value.ciphertext) // 32 bytes
yield Buffer.from(value.tag) // 16 bytes
},
// round 4
function * (value) {
yield Buffer.from([ value.parameters.threshold ]) // 1 byte
yield Buffer.from([ value.parameters.share_count ]) // 1 byte
for (let x of value.commitments) {
yield makeBuffer(x.x)
yield makeBuffer(x.y)
}
},
// round 5
function * (value) {
yield makeBuffer(value.pk.x)
yield makeBuffer(value.pk.y)
yield makeBuffer(value.pk_t_rand_commitment.x)
yield makeBuffer(value.pk_t_rand_commitment.y)
yield makeBuffer(value.challenge_response)
}
]
const signEncoders = [
// round 0
function * (value) {
yield Buffer.from([ value ])
},
// round 1
function * (value) {
yield makeBuffer(value[0].com)
yield makeBuffer(value[1].c, 512)
},
// round 2
function * (value) {
for (let i = 0; i < 2; i++) {
yield makeBuffer(value[i].c, 512)
yield makeBuffer(value[i].b_proof.pk.x)
yield makeBuffer(value[i].b_proof.pk.y)
yield makeBuffer(value[i].b_proof.pk_t_rand_commitment.x)
yield makeBuffer(value[i].b_proof.pk_t_rand_commitment.y)
yield makeBuffer(value[i].b_proof.challenge_response)
yield makeBuffer(value[i].beta_tag_proof.pk.x)
yield makeBuffer(value[i].beta_tag_proof.pk.y)
yield makeBuffer(value[i].beta_tag_proof.pk_t_rand_commitment.x)
yield makeBuffer(value[i].beta_tag_proof.pk_t_rand_commitment.y)
yield makeBuffer(value[i].beta_tag_proof.challenge_response)
}
},
// round 3
function * (value) {
yield makeBuffer(value)
},
// round 4
function * (value) {
yield makeBuffer(value.blind_factor)
yield makeBuffer(value.g_gamma_i.x)
yield makeBuffer(value.g_gamma_i.y)
},
// round 5
function * (value) {
yield makeBuffer(value.com)
},
// round 6
function * (value) {
yield makeBuffer(value[0].V_i.x)
yield makeBuffer(value[0].V_i.y)
yield makeBuffer(value[0].A_i.x)
yield makeBuffer(value[0].A_i.y)
yield makeBuffer(value[0].B_i.x)
yield makeBuffer(value[0].B_i.y)
yield makeBuffer(value[0].blind_factor)
yield makeBuffer(value[1].T.x)
yield makeBuffer(value[1].T.y)
yield makeBuffer(value[1].A3.x)
yield makeBuffer(value[1].A3.y)
yield makeBuffer(value[1].z1)
yield makeBuffer(value[1].z2)
},
// round 7
function * (value) {
yield makeBuffer(value.com)
},
// round 8
function * (value) {
yield makeBuffer(value.u_i.x)
yield makeBuffer(value.u_i.y)
yield makeBuffer(value.t_i.x)
yield makeBuffer(value.t_i.y)
yield makeBuffer(value.blind_factor)
},
// round 9
function * (value) {
yield makeBuffer(value)
},
]
module.exports = function (isKeygen, round, value) {
const parsedValue = JSON.parse(value)
const roundNumber = parseInt(round[round.length - 1])
const encoder = (isKeygen ? keygenEncoders : signEncoders)[roundNumber]
const generator = encoder(parsedValue)
const buffers = []
let next
while (true) {
next = generator.next()
if (next.done)
break
buffers.push(next.value)
}
const encoded = Buffer.concat(buffers)
console.log(`Raw data: ${value.length} bytes, encoded data: ${encoded.length} bytes`)
return encoded
}
module.exports(true, 'round2', '{"blind_factor":"11223344556677889900", "y_i":{"x":"00112233445566778899", "y":"00112233445566778899"}}')

View File

@ -6,6 +6,9 @@ const bech32 = require('bech32')
const axios = require('axios')
const BN = require('bignumber.js')
const encode = require('./encode')
const decode = require('./decode')
const {
HOME_RPC_URL, HOME_BRIDGE_ADDRESS, SIDE_RPC_URL, SIDE_SHARED_DB_ADDRESS, VALIDATOR_PRIVATE_KEY, HOME_CHAIN_ID,
SIDE_CHAIN_ID, HOME_TOKEN_ADDRESS, FOREIGN_URL, FOREIGN_ASSET
@ -91,9 +94,12 @@ async function get (req, res) {
const data = await sharedDb.methods.getData(from, sideWeb3.utils.sha3(uuid), key).call()
const result = homeWeb3.utils.hexToUtf8(data)
if (result.length)
res.send(Ok({ key: req.body.key, value: result }))
if (data.length > 2) {
console.log(data)
const decoded = decode(uuid[0] === 'k', round, data)
console.log(decoded)
res.send(Ok({ key: req.body.key, value: decoded }))
}
else {
setTimeout(() => res.send(Err(null)), 1000)
}
@ -108,7 +114,11 @@ async function set (req, res) {
const to = Number(req.body.key.fourth)
const key = homeWeb3.utils.sha3(`${round}_${to}`)
const query = sharedDb.methods.setData(sideWeb3.utils.sha3(uuid), key, sideWeb3.utils.utf8ToHex(req.body.value))
console.log(req.body.value)
const encoded = encode(uuid[0] === 'k', round, req.body.value)
console.log(encoded.toString('hex'))
const query = sharedDb.methods.setData(sideWeb3.utils.sha3(uuid), key, encoded)
await sideSendQuery(query)
res.send(Ok(null))
@ -299,7 +309,7 @@ async function voteRemoveValidator (req, res) {
async function info (req, res) {
console.log('Info start')
const [x, y, epoch, nextEpoch, threshold, nextThreshold, validators, nextValidators, homeBalance, status] = await Promise.all([
const [ x, y, epoch, nextEpoch, threshold, nextThreshold, validators, nextValidators, homeBalance, status ] = await Promise.all([
bridge.methods.getX().call().then(x => new BN(x).toString(16)),
bridge.methods.getY().call().then(x => new BN(x).toString(16)),
bridge.methods.epoch().call().then(x => x.toNumber()),
@ -335,7 +345,7 @@ async function transfer (req, res) {
const { hash, to, value } = req.body
if (homeWeb3.utils.isAddress(to)) {
console.log(`Calling transfer to ${to}, ${value} tokens`)
const query = bridge.methods.transfer(hash, to, '0x'+(new BN(value).toString(16)))
const query = bridge.methods.transfer(hash, to, '0x' + (new BN(value).toString(16)))
await homeSendQuery(query)
} else {
// return funds ?

View File

@ -7,6 +7,7 @@
"express": "4.17.1",
"async-lock": "1.2.0",
"axios": "0.19.0",
"bignumber.js": "9.0.0"
"bignumber.js": "9.0.0",
"bn.js": "5.0.0"
}
}

View File

@ -206,8 +206,11 @@ function sendTx (tx) {
.catch(err => {
if (err.response.data.message.includes('Tx already exists in cache'))
console.log('Tx already exists in cache')
else
else {
console.log(err.response)
console.log('Something failed, restarting')
return new Promise(resolve => setTimeout(() => resolve(sendTx(tx)), 1000))
}
})
}

View File

@ -14,14 +14,14 @@ async function main () {
let to = process.argv[2]
if (to == "bridge") {
if (to === "bridge") {
to = HOME_BRIDGE_ADDRESS
}
}
const amount = parseInt(process.argv[3])
let coins = process.argv[4]
if (amount != 0) {
if (amount !== 0) {
console.log(`Transfer from ${sender} to ${to}, ${amount} tokens`)
const query = token.methods.transfer(to, '0x'+(new BN(amount).toString(16)))