Browse Source

Compiler fixes. Updates for coins.

cl-refactor
Gav Wood 11 years ago
parent
commit
44525c5f06
  1. 41
      alethzero/MainWin.cpp
  2. 4
      libethereum/Client.cpp
  3. 2
      liblll/Assembly.cpp
  4. 3
      liblll/CodeFragment.cpp
  5. 16
      liblll/CompilerState.cpp
  6. 2
      liblll/CompilerState.h
  7. 13
      liblll/Parser.cpp
  8. 147
      stdserv.js

41
alethzero/MainWin.cpp

@ -274,6 +274,18 @@ void Main::eval(QString const& _js)
ui->jsConsole->setHtml(s); ui->jsConsole->setHtml(s);
} }
QString fromRaw(eth::h256 _n)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
if (s.find_first_of('\0') != string::npos)
s.resize(s.find_first_of('\0'));
return QString::fromStdString(s);
}
return QString();
}
QString Main::pretty(eth::Address _a) const QString Main::pretty(eth::Address _a) const
{ {
h256 n; h256 n;
@ -284,14 +296,7 @@ QString Main::pretty(eth::Address _a) const
if (!n) if (!n)
n = state().storage(m_nameReg, (u160)(_a)); n = state().storage(m_nameReg, (u160)(_a));
if (n) return fromRaw(n);
{
std::string s((char const*)n.data(), 32);
if (s.find_first_of('\0') != string::npos)
s.resize(s.find_first_of('\0'));
return QString::fromStdString(s);
}
return QString();
} }
QString Main::render(eth::Address _a) const QString Main::render(eth::Address _a) const
@ -494,7 +499,7 @@ void Main::updateBlockCount()
{ {
auto d = m_client->blockChain().details(); auto d = m_client->blockChain().details();
auto diff = BlockInfo(m_client->blockChain().block()).difficulty; auto diff = BlockInfo(m_client->blockChain().block()).difficulty;
ui->blockCount->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff))); ui->blockCount->setText(QString("#%1 @%3 T%2 N%4").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(eth::c_protocolVersion));
} }
void Main::on_blockChainFilter_textChanged() void Main::on_blockChainFilter_textChanged()
@ -659,8 +664,11 @@ void Main::refresh(bool _override)
m_keysChanged = false; m_keysChanged = false;
ui->ourAccounts->clear(); ui->ourAccounts->clear();
u256 totalBalance = 0; u256 totalBalance = 0;
u256 totalGavCoinBalance = 0; map<Address, pair<QString, u256>> altCoins;
Address gavCoin = fromString("GavCoin"); Address coinsAddr = right160(st.storage(c_config, 1));
for (unsigned i = 0; i < st.storage(coinsAddr, 0); ++i)
altCoins[right160(st.storage(coinsAddr, st.storage(coinsAddr, i + 1)))] = make_pair(fromRaw(st.storage(coinsAddr, i + 1)), 0);
// u256 totalGavCoinBalance = 0;
for (auto i: m_myKeys) for (auto i: m_myKeys)
{ {
u256 b = st.balance(i.address()); u256 b = st.balance(i.address());
@ -668,10 +676,15 @@ void Main::refresh(bool _override)
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size)); ->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b; totalBalance += b;
totalGavCoinBalance += st.storage(gavCoin, (u160)i.address()); for (auto& c: altCoins)
c.second.second += (u256)st.storage(c.first, (u160)i.address());
} }
ui->balance->setText(QString::fromStdString(toString(totalGavCoinBalance) + " GAV | " + formatBalance(totalBalance))); QString b;
for (auto const& c: altCoins)
if (c.second.second)
b += QString::fromStdString(toString(c.second.second)) + " " + c.second.first.toUpper() + " | ";
ui->balance->setText(b + QString::fromStdString(formatBalance(totalBalance)));
} }
} }
@ -1019,7 +1032,7 @@ void Main::on_data_textChanged()
QString s = ui->data->toPlainText(); QString s = ui->data->toPlainText();
while (s.size()) while (s.size())
{ {
QRegExp r("(@|\\$)?\"(.*)\"(.*)"); QRegExp r("(@|\\$)?\"([^\"]*)\"(.*)");
QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(.*)"); QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(.*)");
if (r.exactMatch(s)) if (r.exactMatch(s))
{ {

4
libethereum/Client.cpp

@ -371,7 +371,7 @@ PastTransactions Client::transactions(TransactionFilter const& _f) const
// Handle pending transactions differently as they're not on the block chain. // Handle pending transactions differently as they're not on the block chain.
if (_f.latest() == 0) if (_f.latest() == 0)
{ {
for (unsigned i = m_postMine.pending().size(); i--;) for (unsigned i = m_postMine.pending().size(); i-- && ret.size() != m;)
if (_f.matches(m_postMine, i)) if (_f.matches(m_postMine, i))
{ {
if (s) if (s)
@ -391,7 +391,7 @@ PastTransactions Client::transactions(TransactionFilter const& _f) const
try try
{ {
State st(m_stateDB, m_bc, h); State st(m_stateDB, m_bc, h);
for (unsigned i = st.pending().size(); i--;) for (unsigned i = st.pending().size(); i-- && ret.size() != m;)
if (_f.matches(st, i)) if (_f.matches(st, i))
{ {
if (s) if (s)

2
liblll/Assembly.cpp

@ -74,12 +74,14 @@ unsigned Assembly::bytesRequired() const
void Assembly::append(Assembly const& _a) void Assembly::append(Assembly const& _a)
{ {
auto newDeposit = m_deposit + _a.deposit();
for (AssemblyItem i: _a.m_items) for (AssemblyItem i: _a.m_items)
{ {
if (i.type() == Tag || i.type() == PushTag) if (i.type() == Tag || i.type() == PushTag)
i.m_data += m_usedTags; i.m_data += m_usedTags;
append(i); append(i);
} }
m_deposit = newDeposit;
m_usedTags += _a.m_usedTags; m_usedTags += _a.m_usedTags;
for (auto const& i: _a.m_data) for (auto const& i: _a.m_data)
m_data.insert(i); m_data.insert(i);

3
liblll/CodeFragment.cpp

@ -151,6 +151,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
case 5: case 5:
us = "SEQ"; us = "SEQ";
break; break;
case 6:
us = "CALLDATALOAD";
break;
default:; default:;
} }

16
liblll/CompilerState.cpp

@ -45,18 +45,20 @@ void CompilerState::populateStandard()
{ {
static const string s = "{" static const string s = "{"
"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)" "(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
"(def 'namereg 0x2d0aceee7e5ab874e22ccf8d1a649f59106d74e8)" "(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
"(def 'config 0xccdeac59d35627b7de09332e819d5159e7bb7250)" "(def 'namereg 0x50441127ea5b9dfd835a9aba4e1dc9c1257b58ca)"
"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)" "(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
"(def 'sendgavcoin (to value) { [0]:to [32]:value (call (- (gas) 21) gavcoin 0 0 64 0 0) })" "(def 'allgas (- (gas) 21))"
"(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })" "(def 'sendgavcoin (to value) { [0]'send [32]:to [64]:value (call allgas gavcoin 0 0 96 0 0) })"
"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))" "(def 'regname (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
"(def 'regcoins (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
"(def 'send (to value) (call allgas to value 0 0 0 0))"
"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))" "(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })" "(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })" "(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })" "(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
"(def 'msg (to value data) { [0]:data (msg (- gas 21) to value 0 32) })" "(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
"(def 'msg (to data) { [0]:data (msg (- gas 21) to 0 0 32) })" "(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })" "(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })" "(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
"(def 'sha3 (val) { [0]:val (sha3 0 32) })" "(def 'sha3 (val) { [0]:val (sha3 0 32) })"

2
liblll/CompilerState.h

@ -41,7 +41,7 @@ struct CompilerState
CodeFragment const& getDef(std::string const& _s); CodeFragment const& getDef(std::string const& _s);
void populateStandard(); void populateStandard();
unsigned stackSize = 64; unsigned stackSize = 128;
std::map<std::string, std::pair<unsigned, unsigned>> vars; ///< maps name to stack offset & size. std::map<std::string, std::pair<unsigned, unsigned>> vars; ///< maps name to stack offset & size.
std::map<std::string, CodeFragment> defs; std::map<std::string, CodeFragment> defs;
std::map<std::string, CodeFragment> args; std::map<std::string, CodeFragment> args;

13
liblll/Parser.cpp

@ -56,6 +56,7 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break; case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break; case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break; case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
default:; default:;
} }
@ -80,8 +81,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
qi::rule<it, qi::ascii::space_type, sp::utree()> element; qi::rule<it, qi::ascii::space_type, sp::utree()> element;
qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"'; qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;@()[]{}:") + '\0'))]; qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))]; qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]]; qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
qi::rule<it, bigint()> integer = intstr; qi::rule<it, bigint()> integer = intstr;
qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether]; qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
@ -92,10 +93,11 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element; qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element; qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element; qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')'; qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; }; auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)]; qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)] | calldataload[x(6)];
element = atom | list | extra; element = atom | list | extra;
string s; string s;
@ -120,7 +122,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
} }
auto ret = s.cbegin(); auto ret = s.cbegin();
qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out); qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
if (ret != s.cend()) for (auto i = ret; i != s.cend(); ++i)
throw std::exception(); if (!isspace(*i))
throw std::exception();
} }

147
stdserv.js

@ -1,44 +1,48 @@
env.note('Creating Config...') env.note('Creating Config...')
var configCode = eth.lll("{ var configCode = eth.lll("
{
[[69]] (caller) [[69]] (caller)
(returnlll (returnlll {
(when (= (caller) @@69) (when (&& (= (calldatasize) 64) (= (caller) @@69))
(for {} (< @i (calldatasize)) [i](+ @i 64) (for {} (< @i (calldatasize)) [i](+ @i 64)
[[ (calldataload @i) ]] (calldataload (+ @i 32)) [[ (calldataload @i) ]] (calldataload (+ @i 32))
) )
) )
) (return @@ $0)
}") })
}
")
env.note('Config code: ' + configCode.unbin()) env.note('Config code: ' + configCode.unbin())
var config = "0x9ef0f0d81e040012600b0c1abdef7c48f720f88a"; var config = "0x9ef0f0d81e040012600b0c1abdef7c48f720f88a";
eth.create(eth.key, '0', configCode, 10000, eth.gasPrice, function(a) { config = a; }) eth.create(eth.key, '0', configCode, 10000, eth.gasPrice, function(a) { config = a; })
env.note('Config at address ' + config) env.note('Config at address ' + config)
var nameRegCode = eth.lll("{ var nameRegCode = eth.lll("
{
[[(address)]] 'NameReg [[(address)]] 'NameReg
[['NameReg]] (address) [['NameReg]] (address)
[[" + config + "]] 'Config [[" + config + "]] 'Config
[['Config]] " + config + " [['Config]] " + config + "
[[69]] (caller) [[69]] (caller)
(returnlll (returnlll {
(if (calldatasize) (when (= $0 'register) {
{ (when @@ $32 (stop))
(when @@(calldataload 0) (stop)) (when @@(caller) [[@@(caller)]] 0)
(when @@(caller) [[@@(caller)]] 0) [[$32]] (caller)
[[(calldataload 0)]] (caller) [[(caller)]] $32
[[(caller)]] (calldataload 0) (stop)
} })
{ (when (&& (= $0 'unregister) @@(caller)) {
(when (= (caller) @@69) (suicide (caller))) [[@@(caller)]] 0
(when @@(caller) { [[(caller)]] 0
[[@@(caller)]] 0 (stop)
[[(caller)]] 0 })
}) (when (&& (= $0 'kill) (= (caller) @@69)) (suicide (caller)))
} (return @@ $0)
) })
) }
}"); ");
env.note('NameReg code: ' + nameRegCode.unbin()) env.note('NameReg code: ' + nameRegCode.unbin())
var nameReg = "0x3face8f2b3ef580265f0f67a57ce0fb78b135613"; var nameReg = "0x3face8f2b3ef580265f0f67a57ce0fb78b135613";
@ -50,22 +54,89 @@ env.note('NameReg at address ' + nameReg)
env.note('Register NameReg...') env.note('Register NameReg...')
eth.transact(eth.key, '0', config, "0".pad(32) + nameReg.pad(32), 10000, eth.gasPrice); eth.transact(eth.key, '0', config, "0".pad(32) + nameReg.pad(32), 10000, eth.gasPrice);
var gavCoinCode = eth.lll("{ var coinsCode = eth.lll("
[[ (caller) ]]: 0x1000000 {
(call (- (gas) 100) " + nameReg + " 0 0 (lit 0 'GavCoin) 0 0) [0]'register [32]'Coins
(returnlll { (msg allgas " + nameReg + " 0 0 64)
(when (!= (calldatasize) 64) (stop)) (returnlll {
[fromBal] @@(caller) (def 'name $0)
[toBal]: @@(calldataload 0) (def 'address (caller))
[value]: (calldataload 32) (when (|| (& 0xffffffffffffffffffffffffff name) @@name) (stop))
(when (< @fromBal @value) (stop)) (set 'n (+ @@0 1))
[[ (caller) ]]: (- @fromBal @value) [[0]] @n
[[ (calldataload 0) ]]: (+ @toBal @value) [[@n]] name
}) [[name]] address
}"); })
}
");
var coins;
env.note('Create Coins...')
eth.create(eth.key, '0', coinsCode, 10000, eth.gasPrice, function(a) { coins = a; })
env.note('Coins at address ' + coins)
env.note('Register Coins...')
eth.transact(eth.key, '0', config, "1".pad(32) + coins.pad(32), 10000, eth.gasPrice);
var gavCoinCode = eth.lll("
{
[[ (caller) ]] 0x1000000
[[ 0x69 ]] (caller)
[[ 0x42 ]] (number)
[0]'register [32]'GavCoin
(msg allgas " + nameReg + " 0 0 64)
(msg " + coins + " 'GAV)
(returnlll {
(when (&& (= $0 'kill) (= (caller) @@0x69)) (suicide (caller)))
(when (= $0 'balance) (return @@$32))
(when (= $0 'approved) (return @@ @(sha3 (^ (if (= (calldatasize) 64) (caller) $64) $32))) )
(when (= $0 'approve) {
[[@(sha3 (^ (caller) $32))]] $32
(stop)
})
(when (= $0 'send) {
(set 'fromVar (if (= (calldatasize) 96)
(caller)
{
(when (! @@ @(sha3 (^ $96 $32)) ) (stop))
$96
}
))
(def 'to $32)
(def 'value $64)
(def 'from (get 'fromVar))
(set 'fromBal @@from)
(when (< @fromBal value) (stop))
[[ from ]]: (- @fromBal value)
[[ to ]]: (+ @@to value)
(stop)
})
(set 'n @@0x42)
(when (&& (|| (= $0 'mine) (! (calldatasize))) (> (number) @n)) {
[[(coinbase)]] (+ @@(coinbase) 1024)
[[0x42]] (+ @n 1)
})
(return @@ $0)
})
}
");
var gavCoin;
env.note('Create GavCoin...') env.note('Create GavCoin...')
eth.create(eth.key, '0', gavCoinCode, 10000, eth.gasPrice); eth.create(eth.key, '0', gavCoinCode, 10000, eth.gasPrice, function(a) { gavCoin = a; });
env.note('Register GavCoin...')
eth.transact(eth.key, '0', config, "2".pad(32) + gavCoin.pad(32), 10000, eth.gasPrice);
env.note('Register my name...')
eth.transact(eth.key, '0', nameReg, "register".pad(32) + "Gav".pad(32), 10000, eth.gasPrice);
env.note('All done.') env.note('All done.')

Loading…
Cancel
Save