github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/internal/neatapi/api.go (about) 1 package neatapi 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "fmt" 8 "math/big" 9 "strings" 10 "time" 11 12 "github.com/neatlab/neatio/chain/consensus" 13 "github.com/neatlab/neatio/chain/consensus/neatcon/epoch" 14 "github.com/neatlab/neatio/chain/core/state" 15 16 "github.com/neatlab/neatio/chain/accounts" 17 "github.com/neatlab/neatio/chain/accounts/abi" 18 "github.com/neatlab/neatio/chain/accounts/keystore" 19 "github.com/neatlab/neatio/chain/core" 20 "github.com/neatlab/neatio/chain/core/rawdb" 21 "github.com/neatlab/neatio/chain/core/types" 22 "github.com/neatlab/neatio/chain/core/vm" 23 "github.com/neatlab/neatio/chain/log" 24 neatAbi "github.com/neatlab/neatio/neatabi/abi" 25 "github.com/neatlab/neatio/network/p2p" 26 "github.com/neatlab/neatio/network/rpc" 27 "github.com/neatlab/neatio/params" 28 "github.com/neatlab/neatio/utilities/common" 29 "github.com/neatlab/neatio/utilities/common/hexutil" 30 "github.com/neatlab/neatio/utilities/common/math" 31 "github.com/neatlab/neatio/utilities/crypto" 32 "github.com/neatlab/neatio/utilities/rlp" 33 goCrypto "github.com/neatlib/crypto-go" 34 "github.com/syndtr/goleveldb/leveldb" 35 ) 36 37 const ( 38 defaultGasPrice = 500 * params.GWei 39 updateValidatorThreshold = 50 40 ) 41 42 var ( 43 minimumRegisterAmount = math.MustParseBig256("50000000000000000000000") 44 45 maxDelegationAddresses = 1000 46 47 maxEditValidatorLength = 100 48 ) 49 50 type PublicNEATChainAPI struct { 51 b Backend 52 } 53 54 func NewPublicNEATChainAPI(b Backend) *PublicNEATChainAPI { 55 return &PublicNEATChainAPI{b} 56 } 57 58 func (s *PublicNEATChainAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { 59 price, err := s.b.SuggestPrice(ctx) 60 return (*hexutil.Big)(price), err 61 } 62 63 func (s *PublicNEATChainAPI) ProtocolVersion() hexutil.Uint { 64 return hexutil.Uint(s.b.ProtocolVersion()) 65 } 66 67 func (s *PublicNEATChainAPI) Syncing() (interface{}, error) { 68 progress := s.b.Downloader().Progress() 69 70 if progress.CurrentBlock >= progress.HighestBlock { 71 return false, nil 72 } 73 74 return map[string]interface{}{ 75 "startingBlock": hexutil.Uint64(progress.StartingBlock), 76 "currentBlock": hexutil.Uint64(progress.CurrentBlock), 77 "highestBlock": hexutil.Uint64(progress.HighestBlock), 78 "pulledStates": hexutil.Uint64(progress.PulledStates), 79 "knownStates": hexutil.Uint64(progress.KnownStates), 80 }, nil 81 } 82 83 type PublicTxPoolAPI struct { 84 b Backend 85 } 86 87 func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { 88 return &PublicTxPoolAPI{b} 89 } 90 91 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 92 content := map[string]map[string]map[string]*RPCTransaction{ 93 "pending": make(map[string]map[string]*RPCTransaction), 94 "queued": make(map[string]map[string]*RPCTransaction), 95 } 96 pending, queue := s.b.TxPoolContent() 97 98 for account, txs := range pending { 99 dump := make(map[string]*RPCTransaction) 100 for _, tx := range txs { 101 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 102 } 103 content["pending"][account.Hex()] = dump 104 } 105 106 for account, txs := range queue { 107 dump := make(map[string]*RPCTransaction) 108 for _, tx := range txs { 109 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 110 } 111 content["queued"][account.Hex()] = dump 112 } 113 return content 114 } 115 116 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { 117 pending, queue := s.b.Stats() 118 return map[string]hexutil.Uint{ 119 "pending": hexutil.Uint(pending), 120 "queued": hexutil.Uint(queue), 121 } 122 } 123 124 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { 125 content := map[string]map[string]map[string]string{ 126 "pending": make(map[string]map[string]string), 127 "queued": make(map[string]map[string]string), 128 } 129 pending, queue := s.b.TxPoolContent() 130 131 var format = func(tx *types.Transaction) string { 132 if to := tx.To(); to != nil { 133 return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 134 } 135 return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) 136 } 137 138 for account, txs := range pending { 139 dump := make(map[string]string) 140 for _, tx := range txs { 141 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 142 } 143 content["pending"][account.Hex()] = dump 144 } 145 146 for account, txs := range queue { 147 dump := make(map[string]string) 148 for _, tx := range txs { 149 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 150 } 151 content["queued"][account.Hex()] = dump 152 } 153 return content 154 } 155 156 type PublicAccountAPI struct { 157 am *accounts.Manager 158 } 159 160 func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { 161 return &PublicAccountAPI{am: am} 162 } 163 164 func (s *PublicAccountAPI) Accounts() []common.Address { 165 addresses := make([]common.Address, 0) 166 for _, wallet := range s.am.Wallets() { 167 for _, account := range wallet.Accounts() { 168 addresses = append(addresses, account.Address) 169 } 170 } 171 return addresses 172 } 173 174 type PrivateAccountAPI struct { 175 am *accounts.Manager 176 nonceLock *AddrLocker 177 b Backend 178 } 179 180 func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { 181 return &PrivateAccountAPI{ 182 am: b.AccountManager(), 183 nonceLock: nonceLock, 184 b: b, 185 } 186 } 187 188 func (s *PrivateAccountAPI) ListAccounts() []common.Address { 189 addresses := make([]common.Address, 0) 190 for _, wallet := range s.am.Wallets() { 191 for _, account := range wallet.Accounts() { 192 addresses = append(addresses, account.Address) 193 } 194 } 195 return addresses 196 } 197 198 type rawWallet struct { 199 URL string `json:"url"` 200 Status string `json:"status"` 201 Failure string `json:"failure,omitempty"` 202 Accounts []accounts.Account `json:"accounts,omitempty"` 203 } 204 205 func (s *PrivateAccountAPI) ListWallets() []rawWallet { 206 wallets := make([]rawWallet, 0) 207 for _, wallet := range s.am.Wallets() { 208 status, failure := wallet.Status() 209 210 raw := rawWallet{ 211 URL: wallet.URL().String(), 212 Status: status, 213 Accounts: wallet.Accounts(), 214 } 215 if failure != nil { 216 raw.Failure = failure.Error() 217 } 218 wallets = append(wallets, raw) 219 } 220 return wallets 221 } 222 223 func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { 224 wallet, err := s.am.Wallet(url) 225 if err != nil { 226 return err 227 } 228 pass := "" 229 if passphrase != nil { 230 pass = *passphrase 231 } 232 return wallet.Open(pass) 233 } 234 235 func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { 236 wallet, err := s.am.Wallet(url) 237 if err != nil { 238 return accounts.Account{}, err 239 } 240 derivPath, err := accounts.ParseDerivationPath(path) 241 if err != nil { 242 return accounts.Account{}, err 243 } 244 if pin == nil { 245 pin = new(bool) 246 } 247 return wallet.Derive(derivPath, *pin) 248 } 249 250 func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { 251 acc, err := fetchKeystore(s.am).NewAccount(password) 252 if err == nil { 253 return acc.Address, nil 254 } 255 return common.Address{}, err 256 } 257 258 func fetchKeystore(am *accounts.Manager) *keystore.KeyStore { 259 return am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 260 } 261 262 func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 263 key, err := crypto.HexToECDSA(privkey) 264 if err != nil { 265 return common.Address{}, err 266 } 267 acc, err := fetchKeystore(s.am).ImportECDSA(key, password) 268 return acc.Address, err 269 } 270 271 func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *uint64) (bool, error) { 272 const max = uint64(time.Duration(math.MaxInt64) / time.Second) 273 var d time.Duration 274 if duration == nil { 275 d = 300 * time.Second 276 } else if *duration > max { 277 return false, errors.New("unlock duration too large") 278 } else { 279 d = time.Duration(*duration) * time.Second 280 } 281 err := fetchKeystore(s.am).TimedUnlock(accounts.Account{Address: addr}, password, d) 282 return err == nil, err 283 } 284 285 func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { 286 return fetchKeystore(s.am).Lock(addr) == nil 287 } 288 289 func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) { 290 291 account := accounts.Account{Address: args.From} 292 wallet, err := s.am.Find(account) 293 if err != nil { 294 return nil, err 295 } 296 297 if err := args.setDefaults(ctx, s.b); err != nil { 298 return nil, err 299 } 300 301 tx := args.toTransaction() 302 303 var chainID *big.Int 304 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 305 chainID = config.ChainId 306 } 307 return wallet.SignTxWithPassphrase(account, passwd, tx, chainID) 308 } 309 310 func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 311 fmt.Printf("transaction args PrivateAccountAPI args %v\n", args) 312 if args.Nonce == nil { 313 314 s.nonceLock.LockAddr(args.From) 315 defer s.nonceLock.UnlockAddr(args.From) 316 } 317 signed, err := s.signTransaction(ctx, args, passwd) 318 if err != nil { 319 return common.Hash{}, err 320 } 321 return submitTransaction(ctx, s.b, signed) 322 } 323 324 func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { 325 326 if args.Gas == nil { 327 return nil, fmt.Errorf("gas not specified") 328 } 329 if args.GasPrice == nil { 330 return nil, fmt.Errorf("gasPrice not specified") 331 } 332 if args.Nonce == nil { 333 return nil, fmt.Errorf("nonce not specified") 334 } 335 signed, err := s.signTransaction(ctx, args, passwd) 336 if err != nil { 337 return nil, err 338 } 339 data, err := rlp.EncodeToBytes(signed) 340 if err != nil { 341 return nil, err 342 } 343 return &SignTransactionResult{data, signed}, nil 344 } 345 346 func signHash(data []byte) []byte { 347 msg := fmt.Sprintf("\x19NEAT Chain Signed Message:\n%d%s", len(data), data) 348 return crypto.Keccak256([]byte(msg)) 349 } 350 351 func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 352 353 account := accounts.Account{Address: addr} 354 355 wallet, err := s.b.AccountManager().Find(account) 356 if err != nil { 357 return nil, err 358 } 359 360 signature, err := wallet.SignHashWithPassphrase(account, passwd, signHash(data)) 361 if err != nil { 362 return nil, err 363 } 364 signature[64] += 27 365 return signature, nil 366 } 367 368 func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { 369 if len(sig) != 65 { 370 return common.Address{}, fmt.Errorf("signature must be 65 bytes long") 371 } 372 if sig[64] != 27 && sig[64] != 28 { 373 return common.Address{}, fmt.Errorf("invalid Neatio signature (V is not 27 or 28)") 374 } 375 sig[64] -= 27 376 377 rpk, err := crypto.SigToPub(signHash(data), sig) 378 if err != nil { 379 return common.Address{}, err 380 } 381 return crypto.PubkeyToAddress(*rpk), nil 382 } 383 384 func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 385 return s.SendTransaction(ctx, args, passwd) 386 } 387 388 type PublicBlockChainAPI struct { 389 b Backend 390 } 391 392 func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { 393 return &PublicBlockChainAPI{b} 394 } 395 396 func (s *PublicBlockChainAPI) ChainId() *hexutil.Big { 397 return (*hexutil.Big)(s.b.ChainConfig().ChainId) 398 } 399 400 func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { 401 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) 402 return hexutil.Uint64(header.Number.Uint64()) 403 } 404 405 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) { 406 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 407 if state == nil || err != nil { 408 return nil, err 409 } 410 return (*hexutil.Big)(state.GetBalance(address)), state.Error() 411 } 412 413 type ProxiedDetail struct { 414 ProxiedBalance *hexutil.Big `json:"proxiedBalance"` 415 DepositProxiedBalance *hexutil.Big `json:"depositProxiedBalance"` 416 PendingRefundBalance *hexutil.Big `json:"pendingRefundBalance"` 417 } 418 419 func (s *PublicBlockChainAPI) GetBalanceDetail(ctx context.Context, address common.Address, blockNr rpc.BlockNumber, fullDetail bool) (map[string]interface{}, error) { 420 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 421 if state == nil || err != nil { 422 return nil, err 423 } 424 425 fields := map[string]interface{}{ 426 "balance": (*hexutil.Big)(state.GetBalance(address)), 427 "depositBalance": (*hexutil.Big)(state.GetDepositBalance(address)), 428 "delegateBalance": (*hexutil.Big)(state.GetDelegateBalance(address)), 429 "proxiedBalance": (*hexutil.Big)(state.GetTotalProxiedBalance(address)), 430 "depositProxiedBalance": (*hexutil.Big)(state.GetTotalDepositProxiedBalance(address)), 431 "pendingRefundBalance": (*hexutil.Big)(state.GetTotalPendingRefundBalance(address)), 432 "rewardBalance": (*hexutil.Big)(state.GetTotalRewardBalance(address)), 433 } 434 435 if fullDetail { 436 proxiedDetail := make(map[common.Address]ProxiedDetail) 437 state.ForEachProxied(address, func(key common.Address, proxiedBalance, depositProxiedBalance, pendingRefundBalance *big.Int) bool { 438 proxiedDetail[key] = ProxiedDetail{ 439 ProxiedBalance: (*hexutil.Big)(proxiedBalance), 440 DepositProxiedBalance: (*hexutil.Big)(depositProxiedBalance), 441 PendingRefundBalance: (*hexutil.Big)(pendingRefundBalance), 442 } 443 return true 444 }) 445 446 fields["proxiedDetail"] = proxiedDetail 447 448 rewardDetail := make(map[common.Address]*hexutil.Big) 449 state.ForEachReward(address, func(key common.Address, rewardBalance *big.Int) bool { 450 rewardDetail[key] = (*hexutil.Big)(rewardBalance) 451 return true 452 }) 453 454 fields["rewardDetail"] = rewardDetail 455 } 456 return fields, state.Error() 457 } 458 459 type EpochLabel uint64 460 461 func (e EpochLabel) MarshalText() ([]byte, error) { 462 output := fmt.Sprintf("epoch_%d", e) 463 return []byte(output), nil 464 } 465 466 func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 467 block, err := s.b.BlockByNumber(ctx, blockNr) 468 if block != nil { 469 response, err := s.rpcOutputBlock(block, true, fullTx) 470 if err == nil && blockNr == rpc.PendingBlockNumber { 471 472 for _, field := range []string{"hash", "nonce", "miner"} { 473 response[field] = nil 474 } 475 } 476 return response, err 477 } 478 return nil, err 479 } 480 481 func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { 482 block, err := s.b.GetBlock(ctx, blockHash) 483 if block != nil { 484 return s.rpcOutputBlock(block, true, fullTx) 485 } 486 return nil, err 487 } 488 489 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 490 block, err := s.b.BlockByNumber(ctx, blockNr) 491 if block != nil { 492 uncles := block.Uncles() 493 if index >= hexutil.Uint(len(uncles)) { 494 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 495 return nil, nil 496 } 497 block = types.NewBlockWithHeader(uncles[index]) 498 return s.rpcOutputBlock(block, false, false) 499 } 500 return nil, err 501 } 502 503 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 504 block, err := s.b.GetBlock(ctx, blockHash) 505 if block != nil { 506 uncles := block.Uncles() 507 if index >= hexutil.Uint(len(uncles)) { 508 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 509 return nil, nil 510 } 511 block = types.NewBlockWithHeader(uncles[index]) 512 return s.rpcOutputBlock(block, false, false) 513 } 514 return nil, err 515 } 516 517 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 518 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 519 n := hexutil.Uint(len(block.Uncles())) 520 return &n 521 } 522 return nil 523 } 524 525 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 526 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 527 n := hexutil.Uint(len(block.Uncles())) 528 return &n 529 } 530 return nil 531 } 532 533 func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 534 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 535 if state == nil || err != nil { 536 return nil, err 537 } 538 code := state.GetCode(address) 539 return code, state.Error() 540 } 541 542 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 543 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 544 if state == nil || err != nil { 545 return nil, err 546 } 547 res := state.GetState(address, common.HexToHash(key)) 548 return res[:], state.Error() 549 } 550 551 type CallArgs struct { 552 From common.Address `json:"from"` 553 To *common.Address `json:"to"` 554 Gas hexutil.Uint64 `json:"gas"` 555 GasPrice hexutil.Big `json:"gasPrice"` 556 Value hexutil.Big `json:"value"` 557 Data hexutil.Bytes `json:"data"` 558 } 559 560 func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) (*core.ExecutionResult, error) { 561 defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 562 563 state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 564 if state == nil || err != nil { 565 return nil, err 566 } 567 568 addr := args.From 569 if addr == (common.Address{}) { 570 if wallets := s.b.AccountManager().Wallets(); len(wallets) > 0 { 571 if accounts := wallets[0].Accounts(); len(accounts) > 0 { 572 addr = accounts[0].Address 573 } 574 } 575 } 576 577 gas, gasPrice := uint64(args.Gas), args.GasPrice.ToInt() 578 if gas == 0 { 579 gas = math.MaxUint64 / 2 580 } 581 if gasPrice.Sign() == 0 { 582 gasPrice = new(big.Int).SetUint64(defaultGasPrice) 583 } 584 585 msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false) 586 587 var cancel context.CancelFunc 588 if timeout > 0 { 589 ctx, cancel = context.WithTimeout(ctx, timeout) 590 } else { 591 ctx, cancel = context.WithCancel(ctx) 592 } 593 594 defer cancel() 595 596 evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) 597 if err != nil { 598 return nil, err 599 } 600 601 go func() { 602 <-ctx.Done() 603 evm.Cancel() 604 }() 605 606 gp := new(core.GasPool).AddGas(math.MaxUint64) 607 result, _, err := core.ApplyMessageEx(evm, msg, gp) 608 if err := vmError(); err != nil { 609 return nil, err 610 } 611 612 if err != nil { 613 return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) 614 } 615 616 return result, err 617 } 618 619 func newRevertError(result *core.ExecutionResult) *revertError { 620 reason, errUnpack := abi.UnpackRevert(result.Revert()) 621 err := errors.New("execution reverted") 622 if errUnpack == nil { 623 err = fmt.Errorf("execution reverted: %v", reason) 624 } 625 return &revertError{ 626 error: err, 627 reason: hexutil.Encode(result.Revert()), 628 } 629 } 630 631 type revertError struct { 632 error 633 reason string 634 } 635 636 func (e *revertError) ErrorCode() int { 637 return 3 638 } 639 640 func (e *revertError) ErrorData() interface{} { 641 return e.reason 642 } 643 644 func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 645 result, err := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second) 646 647 if err != nil { 648 return nil, err 649 } 650 651 if len(result.Revert()) > 0 { 652 return nil, newRevertError(result) 653 } 654 return result.Return(), result.Err 655 } 656 657 func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) { 658 659 var ( 660 lo uint64 = params.TxGas - 1 661 hi uint64 662 cap uint64 663 ) 664 665 functionType, e := neatAbi.FunctionTypeFromId(args.Data[:4]) 666 if e == nil && functionType != neatAbi.Unknown { 667 fmt.Printf("neatio inner contract tx, address: %v, functionType: %v\n", args.To.Hex(), functionType) 668 return hexutil.Uint64(functionType.RequiredGas()), nil 669 } 670 671 if uint64(args.Gas) >= params.TxGas { 672 hi = uint64(args.Gas) 673 } else { 674 675 block, err := s.b.BlockByNumber(ctx, rpc.PendingBlockNumber) 676 if err != nil { 677 return 0, err 678 } 679 hi = block.GasLimit() 680 } 681 cap = hi 682 683 executable := func(gas uint64) (bool, *core.ExecutionResult, error) { 684 args.Gas = hexutil.Uint64(gas) 685 686 result, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}, 0) 687 688 if err != nil { 689 if errors.Is(err, core.ErrIntrinsicGas) { 690 return true, nil, nil 691 } 692 return true, nil, err 693 } 694 return result.Failed(), result, nil 695 } 696 697 for lo+1 < hi { 698 699 mid := (hi + lo) / 2 700 failed, _, err := executable(mid) 701 702 if err != nil { 703 return 0, err 704 } 705 if failed { 706 lo = mid 707 } else { 708 hi = mid 709 } 710 } 711 712 if hi == cap { 713 714 failed, result, err := executable(hi) 715 if err != nil { 716 return 0, err 717 } 718 if failed { 719 if result != nil && result.Err != vm.ErrOutOfGas { 720 if len(result.Revert()) > 0 { 721 return 0, newRevertError(result) 722 } 723 return 0, result.Err 724 } 725 726 return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) 727 } 728 } 729 return hexutil.Uint64(hi), nil 730 } 731 732 type ExecutionResult struct { 733 Gas uint64 `json:"gas"` 734 Failed bool `json:"failed"` 735 ReturnValue string `json:"returnValue"` 736 StructLogs []StructLogRes `json:"structLogs"` 737 } 738 739 type StructLogRes struct { 740 Pc uint64 `json:"pc"` 741 Op string `json:"op"` 742 Gas uint64 `json:"gas"` 743 GasCost uint64 `json:"gasCost"` 744 Depth int `json:"depth"` 745 Error error `json:"error,omitempty"` 746 Stack *[]string `json:"stack,omitempty"` 747 Memory *[]string `json:"memory,omitempty"` 748 Storage *map[string]string `json:"storage,omitempty"` 749 } 750 751 func FormatLogs(logs []vm.StructLog) []StructLogRes { 752 formatted := make([]StructLogRes, len(logs)) 753 for index, trace := range logs { 754 formatted[index] = StructLogRes{ 755 Pc: trace.Pc, 756 Op: trace.Op.String(), 757 Gas: trace.Gas, 758 GasCost: trace.GasCost, 759 Depth: trace.Depth, 760 Error: trace.Err, 761 } 762 if trace.Stack != nil { 763 stack := make([]string, len(trace.Stack)) 764 for i, stackValue := range trace.Stack { 765 stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32)) 766 } 767 formatted[index].Stack = &stack 768 } 769 if trace.Memory != nil { 770 memory := make([]string, 0, (len(trace.Memory)+31)/32) 771 for i := 0; i+32 <= len(trace.Memory); i += 32 { 772 memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) 773 } 774 formatted[index].Memory = &memory 775 } 776 if trace.Storage != nil { 777 storage := make(map[string]string) 778 for i, storageValue := range trace.Storage { 779 storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) 780 } 781 formatted[index].Storage = &storage 782 } 783 } 784 return formatted 785 } 786 787 func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 788 head := b.Header() 789 fields := map[string]interface{}{ 790 "number": (*hexutil.Big)(head.Number), 791 792 "hash": b.Hash(), 793 "parentHash": head.ParentHash, 794 "nonce": head.Nonce, 795 "mixHash": head.MixDigest, 796 "sha3Uncles": head.UncleHash, 797 "logsBloom": head.Bloom, 798 "stateRoot": head.Root, 799 "miner": head.Coinbase, 800 "difficulty": (*hexutil.Big)(head.Difficulty), 801 "totalDifficulty": (*hexutil.Big)(s.b.GetTd(b.Hash())), 802 "extraData": hexutil.Bytes(head.Extra), 803 "size": hexutil.Uint64(b.Size()), 804 "gasLimit": hexutil.Uint64(head.GasLimit), 805 "gasUsed": hexutil.Uint64(head.GasUsed), 806 "timestamp": (*hexutil.Big)(head.Time), 807 "transactionsRoot": head.TxHash, 808 "receiptsRoot": head.ReceiptHash, 809 } 810 811 if inclTx { 812 formatTx := func(tx *types.Transaction) (interface{}, error) { 813 return tx.Hash(), nil 814 } 815 816 if fullTx { 817 formatTx = func(tx *types.Transaction) (interface{}, error) { 818 return newRPCTransactionFromBlockHash(b, tx.Hash()), nil 819 } 820 } 821 822 txs := b.Transactions() 823 transactions := make([]interface{}, len(txs)) 824 var err error 825 for i, tx := range b.Transactions() { 826 if transactions[i], err = formatTx(tx); err != nil { 827 return nil, err 828 } 829 } 830 fields["transactions"] = transactions 831 } 832 833 uncles := b.Uncles() 834 uncleHashes := make([]common.Hash, len(uncles)) 835 for i, uncle := range uncles { 836 uncleHashes[i] = uncle.Hash() 837 } 838 fields["uncles"] = uncleHashes 839 840 return fields, nil 841 } 842 843 type RPCTransaction struct { 844 BlockHash common.Hash `json:"blockHash"` 845 BlockNumber *hexutil.Big `json:"blockNumber"` 846 From common.Address `json:"from"` 847 Gas hexutil.Uint64 `json:"gas"` 848 GasPrice *hexutil.Big `json:"gasPrice"` 849 Hash common.Hash `json:"hash"` 850 Input hexutil.Bytes `json:"input"` 851 Nonce hexutil.Uint64 `json:"nonce"` 852 To *common.Address `json:"to"` 853 TransactionIndex hexutil.Uint `json:"transactionIndex"` 854 Value *hexutil.Big `json:"value"` 855 V *hexutil.Big `json:"v"` 856 R *hexutil.Big `json:"r"` 857 S *hexutil.Big `json:"s"` 858 } 859 860 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { 861 var signer types.Signer = types.FrontierSigner{} 862 if tx.Protected() { 863 signer = types.NewEIP155Signer(tx.ChainId()) 864 } 865 from, _ := types.Sender(signer, tx) 866 v, r, s := tx.RawSignatureValues() 867 868 result := &RPCTransaction{ 869 From: from, 870 Gas: hexutil.Uint64(tx.Gas()), 871 GasPrice: (*hexutil.Big)(tx.GasPrice()), 872 Hash: tx.Hash(), 873 Input: hexutil.Bytes(tx.Data()), 874 Nonce: hexutil.Uint64(tx.Nonce()), 875 To: tx.To(), 876 Value: (*hexutil.Big)(tx.Value()), 877 V: (*hexutil.Big)(v), 878 R: (*hexutil.Big)(r), 879 S: (*hexutil.Big)(s), 880 } 881 if blockHash != (common.Hash{}) { 882 result.BlockHash = blockHash 883 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 884 result.TransactionIndex = hexutil.Uint(index) 885 } 886 return result 887 } 888 889 func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { 890 return newRPCTransaction(tx, common.Hash{}, 0, 0) 891 } 892 893 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { 894 txs := b.Transactions() 895 if index >= uint64(len(txs)) { 896 return nil 897 } 898 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) 899 } 900 901 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 902 txs := b.Transactions() 903 if index >= uint64(len(txs)) { 904 return nil 905 } 906 blob, _ := rlp.EncodeToBytes(txs[index]) 907 return blob 908 } 909 910 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { 911 for idx, tx := range b.Transactions() { 912 if tx.Hash() == hash { 913 return newRPCTransactionFromBlockIndex(b, uint64(idx)) 914 } 915 } 916 return nil 917 } 918 919 type PublicTransactionPoolAPI struct { 920 b Backend 921 nonceLock *AddrLocker 922 } 923 924 func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { 925 return &PublicTransactionPoolAPI{b, nonceLock} 926 } 927 928 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 929 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 930 n := hexutil.Uint(len(block.Transactions())) 931 return &n 932 } 933 return nil 934 } 935 936 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 937 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 938 n := hexutil.Uint(len(block.Transactions())) 939 return &n 940 } 941 return nil 942 } 943 944 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 945 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 946 return newRPCTransactionFromBlockIndex(block, uint64(index)) 947 } 948 return nil 949 } 950 951 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 952 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 953 return newRPCTransactionFromBlockIndex(block, uint64(index)) 954 } 955 return nil 956 } 957 958 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 959 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 960 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 961 } 962 return nil 963 } 964 965 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 966 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 967 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 968 } 969 return nil 970 } 971 972 func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { 973 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 974 if state == nil || err != nil { 975 return nil, err 976 } 977 nonce := state.GetNonce(address) 978 return (*hexutil.Uint64)(&nonce), state.Error() 979 } 980 981 func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction { 982 983 if tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash); tx != nil { 984 return newRPCTransaction(tx, blockHash, blockNumber, index) 985 } 986 987 if tx := s.b.GetPoolTransaction(hash); tx != nil { 988 return newRPCPendingTransaction(tx) 989 } 990 991 return nil 992 } 993 994 func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 995 var tx *types.Transaction 996 997 if tx, _, _, _ = rawdb.ReadTransaction(s.b.ChainDb(), hash); tx == nil { 998 if tx = s.b.GetPoolTransaction(hash); tx == nil { 999 1000 return nil, nil 1001 } 1002 } 1003 1004 return rlp.EncodeToBytes(tx) 1005 } 1006 1007 type Log struct { 1008 Address string `json:"address" gencodec:"required"` 1009 1010 Topics []common.Hash `json:"topics" gencodec:"required"` 1011 1012 Data string `json:"data" gencodec:"required"` 1013 1014 BlockNumber uint64 `json:"blockNumber"` 1015 1016 TxHash common.Hash `json:"transactionHash" gencodec:"required"` 1017 1018 TxIndex uint `json:"transactionIndex" gencodec:"required"` 1019 1020 BlockHash common.Hash `json:"blockHash"` 1021 1022 Index uint `json:"logIndex" gencodec:"required"` 1023 1024 Removed bool `json:"removed"` 1025 } 1026 1027 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1028 tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) 1029 if tx == nil { 1030 return nil, nil 1031 } 1032 receipts, err := s.b.GetReceipts(ctx, blockHash) 1033 if err != nil { 1034 return nil, err 1035 } 1036 if len(receipts) <= int(index) { 1037 return nil, nil 1038 } 1039 receipt := receipts[index] 1040 1041 var signer types.Signer = types.FrontierSigner{} 1042 if tx.Protected() { 1043 signer = types.NewEIP155Signer(tx.ChainId()) 1044 } 1045 from, _ := types.Sender(signer, tx) 1046 1047 fields := map[string]interface{}{ 1048 "blockHash": blockHash, 1049 "blockNumber": hexutil.Uint64(blockNumber), 1050 "transactionHash": hash, 1051 "transactionIndex": hexutil.Uint64(index), 1052 "from": from, 1053 "to": tx.To(), 1054 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1055 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1056 "contractAddress": nil, 1057 "logs": receipt.Logs, 1058 "logsBloom": receipt.Bloom, 1059 } 1060 1061 if len(receipt.PostState) > 0 { 1062 fields["root"] = hexutil.Bytes(receipt.PostState) 1063 } else { 1064 fields["status"] = hexutil.Uint(receipt.Status) 1065 } 1066 if receipt.Logs == nil { 1067 fields["logs"] = [][]*types.Log{} 1068 } 1069 1070 if receipt.ContractAddress != (common.Address{}) { 1071 fields["contractAddress"] = receipt.ContractAddress 1072 } 1073 return fields, nil 1074 } 1075 1076 func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1077 1078 account := accounts.Account{Address: addr} 1079 1080 wallet, err := s.b.AccountManager().Find(account) 1081 if err != nil { 1082 return nil, err 1083 } 1084 1085 var chainID *big.Int 1086 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 1087 chainID = config.ChainId 1088 } 1089 return wallet.SignTxWithAddress(account, tx, chainID) 1090 } 1091 1092 type SendTxArgs struct { 1093 From common.Address `json:"from"` 1094 To *common.Address `json:"to"` 1095 Gas *hexutil.Uint64 `json:"gas"` 1096 GasPrice *hexutil.Big `json:"gasPrice"` 1097 Value *hexutil.Big `json:"value"` 1098 Nonce *hexutil.Uint64 `json:"nonce"` 1099 1100 Data *hexutil.Bytes `json:"data"` 1101 Input *hexutil.Bytes `json:"input"` 1102 } 1103 1104 func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { 1105 1106 var function = neatAbi.Unknown 1107 if neatAbi.IsNeatChainContractAddr(args.To) { 1108 var input []byte 1109 if args.Data != nil { 1110 input = *args.Data 1111 } else if args.Input != nil { 1112 input = *args.Input 1113 } 1114 if len(input) == 0 { 1115 return errors.New(`neatio contract without any data provided`) 1116 } 1117 1118 var err error 1119 function, err = neatAbi.FunctionTypeFromId(input[:4]) 1120 if err != nil { 1121 return err 1122 } 1123 } 1124 1125 if function == neatAbi.DepositInSideChain || function == neatAbi.WithdrawFromMainChain || function == neatAbi.SaveDataToMainChain { 1126 args.Gas = new(hexutil.Uint64) 1127 *(*uint64)(args.Gas) = 0 1128 } else { 1129 if args.Gas == nil { 1130 args.Gas = new(hexutil.Uint64) 1131 *(*uint64)(args.Gas) = 90000 1132 } 1133 } 1134 1135 if args.GasPrice == nil { 1136 price, err := b.SuggestPrice(ctx) 1137 if err != nil { 1138 return err 1139 } 1140 args.GasPrice = (*hexutil.Big)(price) 1141 } 1142 if args.Value == nil { 1143 args.Value = new(hexutil.Big) 1144 } 1145 if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { 1146 return errors.New(`Both "data" and "input" are set and not equal. Please use "input" to pass transaction call data.`) 1147 } 1148 if args.To == nil { 1149 1150 var input []byte 1151 if args.Data != nil { 1152 input = *args.Data 1153 } else if args.Input != nil { 1154 input = *args.Input 1155 } 1156 if len(input) == 0 { 1157 return errors.New(`contract creation without any data provided`) 1158 } 1159 } 1160 1161 if args.Nonce == nil { 1162 nonce, err := b.GetPoolNonce(ctx, args.From) 1163 if err != nil { 1164 return err 1165 } 1166 args.Nonce = (*hexutil.Uint64)(&nonce) 1167 } 1168 1169 return nil 1170 } 1171 1172 func (args *SendTxArgs) toTransaction() *types.Transaction { 1173 var input []byte 1174 if args.Data != nil { 1175 input = *args.Data 1176 } else if args.Input != nil { 1177 input = *args.Input 1178 } 1179 if args.To == nil { 1180 return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) 1181 } 1182 return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) 1183 } 1184 1185 func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1186 if err := b.SendTx(ctx, tx); err != nil { 1187 return common.Hash{}, err 1188 } 1189 if tx.To() == nil { 1190 signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) 1191 from, err := types.Sender(signer, tx) 1192 if err != nil { 1193 return common.Hash{}, err 1194 } 1195 addr := crypto.CreateAddress(from, tx.Nonce()) 1196 log.Info("Submitted contract creation", "fullhash", tx.Hash().Hex(), "contract", addr.Hex()) 1197 } else { 1198 log.Info("Submitted transaction", "fullhash", tx.Hash().Hex(), "recipient", tx.To()) 1199 } 1200 return tx.Hash(), nil 1201 } 1202 1203 func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { 1204 fmt.Printf("transaction args PublicTransactionPoolAPI args %v\n", args) 1205 1206 account := accounts.Account{Address: args.From} 1207 1208 wallet, err := s.b.AccountManager().Find(account) 1209 if err != nil { 1210 return common.Hash{}, err 1211 } 1212 1213 if args.Nonce == nil { 1214 1215 s.nonceLock.LockAddr(args.From) 1216 defer s.nonceLock.UnlockAddr(args.From) 1217 } 1218 1219 if err := args.setDefaults(ctx, s.b); err != nil { 1220 return common.Hash{}, err 1221 } 1222 1223 tx := args.toTransaction() 1224 1225 var chainID *big.Int 1226 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 1227 chainID = config.ChainId 1228 } 1229 signed, err := wallet.SignTxWithAddress(account, tx, chainID) 1230 if err != nil { 1231 return common.Hash{}, err 1232 } 1233 return submitTransaction(ctx, s.b, signed) 1234 } 1235 1236 func SendTransaction(ctx context.Context, args SendTxArgs, am *accounts.Manager, b Backend, nonceLock *AddrLocker) (common.Hash, error) { 1237 fmt.Printf("transaction args PublicTransactionPoolAPI args %v\n", args) 1238 1239 account := accounts.Account{Address: args.From} 1240 1241 wallet, err := am.Find(account) 1242 if err != nil { 1243 return common.Hash{}, err 1244 } 1245 1246 if args.Nonce == nil { 1247 1248 nonceLock.LockAddr(args.From) 1249 defer nonceLock.UnlockAddr(args.From) 1250 } 1251 1252 if err := args.setDefaults(ctx, b); err != nil { 1253 return common.Hash{}, err 1254 } 1255 1256 tx := args.toTransaction() 1257 1258 var chainID *big.Int 1259 if config := b.ChainConfig(); config.IsEIP155(b.CurrentBlock().Number()) { 1260 chainID = config.ChainId 1261 } 1262 signed, err := wallet.SignTxWithAddress(account, tx, chainID) 1263 if err != nil { 1264 return common.Hash{}, err 1265 } 1266 return submitTransaction(ctx, b, signed) 1267 } 1268 1269 func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { 1270 tx := new(types.Transaction) 1271 if err := rlp.DecodeBytes(encodedTx, tx); err != nil { 1272 return common.Hash{}, err 1273 } 1274 return submitTransaction(ctx, s.b, tx) 1275 } 1276 1277 func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1278 1279 account := accounts.Account{Address: addr} 1280 1281 wallet, err := s.b.AccountManager().Find(account) 1282 if err != nil { 1283 return nil, err 1284 } 1285 1286 signature, err := wallet.SignHash(account, signHash(data)) 1287 if err == nil { 1288 signature[64] += 27 1289 } 1290 return signature, err 1291 } 1292 1293 type SignTransactionResult struct { 1294 Raw hexutil.Bytes `json:"raw"` 1295 Tx *types.Transaction `json:"tx"` 1296 } 1297 1298 func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 1299 if args.Gas == nil { 1300 return nil, fmt.Errorf("gas not specified") 1301 } 1302 if args.GasPrice == nil { 1303 return nil, fmt.Errorf("gasPrice not specified") 1304 } 1305 if args.Nonce == nil { 1306 return nil, fmt.Errorf("nonce not specified") 1307 } 1308 if err := args.setDefaults(ctx, s.b); err != nil { 1309 return nil, err 1310 } 1311 tx, err := s.sign(args.From, args.toTransaction()) 1312 if err != nil { 1313 return nil, err 1314 } 1315 data, err := rlp.EncodeToBytes(tx) 1316 if err != nil { 1317 return nil, err 1318 } 1319 return &SignTransactionResult{data, tx}, nil 1320 } 1321 1322 func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { 1323 pending, err := s.b.GetPoolTransactions() 1324 if err != nil { 1325 return nil, err 1326 } 1327 1328 transactions := make([]*RPCTransaction, 0, len(pending)) 1329 for _, tx := range pending { 1330 var signer types.Signer = types.HomesteadSigner{} 1331 if tx.Protected() { 1332 signer = types.NewEIP155Signer(tx.ChainId()) 1333 } 1334 from, _ := types.Sender(signer, tx) 1335 if _, err := s.b.AccountManager().Find(accounts.Account{Address: from}); err == nil { 1336 transactions = append(transactions, newRPCPendingTransaction(tx)) 1337 } 1338 } 1339 return transactions, nil 1340 } 1341 1342 func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { 1343 if sendArgs.Nonce == nil { 1344 return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") 1345 } 1346 if err := sendArgs.setDefaults(ctx, s.b); err != nil { 1347 return common.Hash{}, err 1348 } 1349 matchTx := sendArgs.toTransaction() 1350 pending, err := s.b.GetPoolTransactions() 1351 if err != nil { 1352 return common.Hash{}, err 1353 } 1354 1355 for _, p := range pending { 1356 var signer types.Signer = types.HomesteadSigner{} 1357 if p.Protected() { 1358 signer = types.NewEIP155Signer(p.ChainId()) 1359 } 1360 wantSigHash := signer.Hash(matchTx) 1361 1362 if pFrom, err := types.Sender(signer, p); err == nil && pFrom == sendArgs.From && signer.Hash(p) == wantSigHash { 1363 1364 if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { 1365 sendArgs.GasPrice = gasPrice 1366 } 1367 if gasLimit != nil && *gasLimit != 0 { 1368 sendArgs.Gas = gasLimit 1369 } 1370 signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) 1371 if err != nil { 1372 return common.Hash{}, err 1373 } 1374 if err = s.b.SendTx(ctx, signedTx); err != nil { 1375 return common.Hash{}, err 1376 } 1377 return signedTx.Hash(), nil 1378 } 1379 } 1380 1381 return common.Hash{}, fmt.Errorf("Transaction %#x not found", matchTx.Hash()) 1382 } 1383 1384 type PublicDebugAPI struct { 1385 b Backend 1386 } 1387 1388 func NewPublicDebugAPI(b Backend) *PublicDebugAPI { 1389 return &PublicDebugAPI{b: b} 1390 } 1391 1392 func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { 1393 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1394 if block == nil { 1395 return "", fmt.Errorf("block #%d not found", number) 1396 } 1397 encoded, err := rlp.EncodeToBytes(block) 1398 if err != nil { 1399 return "", err 1400 } 1401 return fmt.Sprintf("%x", encoded), nil 1402 } 1403 1404 func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 1405 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1406 if block == nil { 1407 return "", fmt.Errorf("block #%d not found", number) 1408 } 1409 return block.String(), nil 1410 } 1411 1412 type PrivateDebugAPI struct { 1413 b Backend 1414 } 1415 1416 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 1417 return &PrivateDebugAPI{b: b} 1418 } 1419 1420 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 1421 ldb, ok := api.b.ChainDb().(interface { 1422 LDB() *leveldb.DB 1423 }) 1424 if !ok { 1425 return "", fmt.Errorf("chaindbProperty does not work for memory databases") 1426 } 1427 if property == "" { 1428 property = "leveldb.stats" 1429 } else if !strings.HasPrefix(property, "leveldb.") { 1430 property = "leveldb." + property 1431 } 1432 return ldb.LDB().GetProperty(property) 1433 } 1434 1435 func (api *PrivateDebugAPI) ChaindbCompact() error { 1436 for b := byte(0); b < 255; b++ { 1437 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 1438 if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { 1439 log.Error("Database compaction failed", "err", err) 1440 return err 1441 } 1442 } 1443 return nil 1444 } 1445 1446 func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { 1447 api.b.SetHead(uint64(number)) 1448 } 1449 1450 type PublicNetAPI struct { 1451 net *p2p.Server 1452 networkVersion uint64 1453 } 1454 1455 func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { 1456 return &PublicNetAPI{net, networkVersion} 1457 } 1458 1459 func (s *PublicNetAPI) Listening() bool { 1460 return true 1461 } 1462 1463 func (s *PublicNetAPI) PeerCount() hexutil.Uint { 1464 return hexutil.Uint(s.net.PeerCount()) 1465 } 1466 1467 func (s *PublicNetAPI) Version() string { 1468 return fmt.Sprintf("%d", s.networkVersion) 1469 } 1470 1471 type PublicNEATAPI struct { 1472 am *accounts.Manager 1473 b Backend 1474 nonceLock *AddrLocker 1475 } 1476 1477 func NewPublicNEATAPI(b Backend, nonceLock *AddrLocker) *PublicNEATAPI { 1478 return &PublicNEATAPI{b.AccountManager(), b, nonceLock} 1479 } 1480 1481 func (s *PublicNEATAPI) SignAddress(from common.Address, consensusPrivateKey hexutil.Bytes) (goCrypto.Signature, error) { 1482 if len(consensusPrivateKey) != 32 { 1483 return nil, errors.New("invalid consensus private key") 1484 } 1485 1486 var blsPriv goCrypto.BLSPrivKey 1487 copy(blsPriv[:], consensusPrivateKey) 1488 1489 blsSign := blsPriv.Sign(from.Bytes()) 1490 1491 return blsSign, nil 1492 } 1493 1494 func (api *PublicNEATAPI) WithdrawReward(ctx context.Context, from common.Address, delegateAddress common.Address, amount *hexutil.Big, gasPrice *hexutil.Big) (common.Hash, error) { 1495 input, err := neatAbi.ChainABI.Pack(neatAbi.WithdrawReward.String(), delegateAddress, (*big.Int)(amount)) 1496 if err != nil { 1497 return common.Hash{}, err 1498 } 1499 1500 defaultGas := neatAbi.WithdrawReward.RequiredGas() 1501 1502 args := SendTxArgs{ 1503 From: from, 1504 To: &neatAbi.NeatioSmartContractAddress, 1505 Gas: (*hexutil.Uint64)(&defaultGas), 1506 GasPrice: gasPrice, 1507 Value: nil, 1508 Input: (*hexutil.Bytes)(&input), 1509 Nonce: nil, 1510 } 1511 1512 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1513 } 1514 1515 func (api *PublicNEATAPI) Delegate(ctx context.Context, from, candidate common.Address, amount *hexutil.Big, gasPrice *hexutil.Big) (common.Hash, error) { 1516 1517 input, err := neatAbi.ChainABI.Pack(neatAbi.Delegate.String(), candidate) 1518 if err != nil { 1519 return common.Hash{}, err 1520 } 1521 1522 defaultGas := neatAbi.Delegate.RequiredGas() 1523 1524 args := SendTxArgs{ 1525 From: from, 1526 To: &neatAbi.NeatioSmartContractAddress, 1527 Gas: (*hexutil.Uint64)(&defaultGas), 1528 GasPrice: gasPrice, 1529 Value: amount, 1530 Input: (*hexutil.Bytes)(&input), 1531 Nonce: nil, 1532 } 1533 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1534 } 1535 1536 func (api *PublicNEATAPI) UnDelegate(ctx context.Context, from, candidate common.Address, amount *hexutil.Big, gasPrice *hexutil.Big) (common.Hash, error) { 1537 1538 input, err := neatAbi.ChainABI.Pack(neatAbi.UnDelegate.String(), candidate, (*big.Int)(amount)) 1539 if err != nil { 1540 return common.Hash{}, err 1541 } 1542 1543 defaultGas := neatAbi.UnDelegate.RequiredGas() 1544 1545 args := SendTxArgs{ 1546 From: from, 1547 To: &neatAbi.NeatioSmartContractAddress, 1548 Gas: (*hexutil.Uint64)(&defaultGas), 1549 GasPrice: gasPrice, 1550 Value: nil, 1551 Input: (*hexutil.Bytes)(&input), 1552 Nonce: nil, 1553 } 1554 1555 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1556 } 1557 1558 func (api *PublicNEATAPI) Register(ctx context.Context, from common.Address, registerAmount *hexutil.Big, pubkey goCrypto.BLSPubKey, signature hexutil.Bytes, commission uint8, gasPrice *hexutil.Big) (common.Hash, error) { 1559 1560 input, err := neatAbi.ChainABI.Pack(neatAbi.Register.String(), pubkey.Bytes(), signature, commission) 1561 if err != nil { 1562 return common.Hash{}, err 1563 } 1564 1565 defaultGas := neatAbi.Register.RequiredGas() 1566 1567 args := SendTxArgs{ 1568 From: from, 1569 To: &neatAbi.NeatioSmartContractAddress, 1570 Gas: (*hexutil.Uint64)(&defaultGas), 1571 GasPrice: gasPrice, 1572 Value: registerAmount, 1573 Input: (*hexutil.Bytes)(&input), 1574 Nonce: nil, 1575 } 1576 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1577 } 1578 1579 func (api *PublicNEATAPI) UnRegister(ctx context.Context, from common.Address, gasPrice *hexutil.Big) (common.Hash, error) { 1580 1581 input, err := neatAbi.ChainABI.Pack(neatAbi.UnRegister.String()) 1582 if err != nil { 1583 return common.Hash{}, err 1584 } 1585 1586 defaultGas := neatAbi.UnRegister.RequiredGas() 1587 1588 args := SendTxArgs{ 1589 From: from, 1590 To: &neatAbi.NeatioSmartContractAddress, 1591 Gas: (*hexutil.Uint64)(&defaultGas), 1592 GasPrice: gasPrice, 1593 Value: nil, 1594 Input: (*hexutil.Bytes)(&input), 1595 Nonce: nil, 1596 } 1597 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1598 } 1599 1600 func (api *PublicNEATAPI) CheckCandidate(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (map[string]interface{}, error) { 1601 state, _, err := api.b.StateAndHeaderByNumber(ctx, blockNr) 1602 if state == nil || err != nil { 1603 return nil, err 1604 } 1605 1606 fields := map[string]interface{}{ 1607 "candidate": state.IsCandidate(address), 1608 "commission": state.GetCommission(address), 1609 } 1610 return fields, state.Error() 1611 } 1612 1613 func (api *PublicNEATAPI) SetCommission(ctx context.Context, from common.Address, commission uint8, gasPrice *hexutil.Big) (common.Hash, error) { 1614 input, err := neatAbi.ChainABI.Pack(neatAbi.SetCommission.String(), commission) 1615 if err != nil { 1616 return common.Hash{}, err 1617 } 1618 1619 defaultGas := neatAbi.SetCommission.RequiredGas() 1620 1621 args := SendTxArgs{ 1622 From: from, 1623 To: &neatAbi.NeatioSmartContractAddress, 1624 Gas: (*hexutil.Uint64)(&defaultGas), 1625 GasPrice: gasPrice, 1626 Value: nil, 1627 Input: (*hexutil.Bytes)(&input), 1628 Nonce: nil, 1629 } 1630 1631 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1632 } 1633 1634 func (api *PublicNEATAPI) EditValidator(ctx context.Context, from common.Address, moniker, website string, identity string, details string, gasPrice *hexutil.Big) (common.Hash, error) { 1635 input, err := neatAbi.ChainABI.Pack(neatAbi.EditValidator.String(), moniker, website, identity, details) 1636 if err != nil { 1637 return common.Hash{}, err 1638 } 1639 1640 defaultGas := neatAbi.EditValidator.RequiredGas() 1641 1642 args := SendTxArgs{ 1643 From: from, 1644 To: &neatAbi.NeatioSmartContractAddress, 1645 Gas: (*hexutil.Uint64)(&defaultGas), 1646 GasPrice: gasPrice, 1647 Value: nil, 1648 Input: (*hexutil.Bytes)(&input), 1649 Nonce: nil, 1650 } 1651 1652 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1653 } 1654 1655 func (api *PublicNEATAPI) SetAddress(ctx context.Context, from, fAddress common.Address, gasPrice *hexutil.Big) (common.Hash, error) { 1656 input, err := neatAbi.ChainABI.Pack(neatAbi.SetAddress.String(), fAddress) 1657 if err != nil { 1658 return common.Hash{}, err 1659 } 1660 1661 defaultGas := neatAbi.SetAddress.RequiredGas() 1662 1663 args := SendTxArgs{ 1664 From: from, 1665 To: &neatAbi.NeatioSmartContractAddress, 1666 Gas: (*hexutil.Uint64)(&defaultGas), 1667 GasPrice: gasPrice, 1668 Value: nil, 1669 Input: (*hexutil.Bytes)(&input), 1670 Nonce: nil, 1671 } 1672 1673 return SendTransaction(ctx, args, api.am, api.b, api.nonceLock) 1674 } 1675 1676 func init() { 1677 1678 core.RegisterValidateCb(neatAbi.WithdrawReward, withdrawRewardValidateCb) 1679 core.RegisterApplyCb(neatAbi.WithdrawReward, withdrawRewardApplyCb) 1680 1681 core.RegisterValidateCb(neatAbi.Delegate, delegateValidateCb) 1682 core.RegisterApplyCb(neatAbi.Delegate, delegateApplyCb) 1683 1684 core.RegisterValidateCb(neatAbi.UnDelegate, unDelegateValidateCb) 1685 core.RegisterApplyCb(neatAbi.UnDelegate, unDelegateApplyCb) 1686 1687 core.RegisterValidateCb(neatAbi.Register, registerValidateCb) 1688 core.RegisterApplyCb(neatAbi.Register, registerApplyCb) 1689 1690 core.RegisterValidateCb(neatAbi.UnRegister, unRegisterValidateCb) 1691 core.RegisterApplyCb(neatAbi.UnRegister, unRegisterApplyCb) 1692 1693 core.RegisterValidateCb(neatAbi.SetCommission, setCommisstionValidateCb) 1694 core.RegisterApplyCb(neatAbi.SetCommission, setCommisstionApplyCb) 1695 1696 core.RegisterValidateCb(neatAbi.EditValidator, editValidatorValidateCb) 1697 1698 core.RegisterValidateCb(neatAbi.SetAddress, setAddressValidateCb) 1699 core.RegisterApplyCb(neatAbi.SetAddress, setAddressApplyCb) 1700 } 1701 1702 func withdrawRewardValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1703 from := derivedAddressFromTx(tx) 1704 _, err := withDrawRewardValidation(from, tx, state, bc) 1705 if err != nil { 1706 return err 1707 } 1708 1709 return nil 1710 } 1711 1712 func withdrawRewardApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 1713 from := derivedAddressFromTx(tx) 1714 1715 args, err := withDrawRewardValidation(from, tx, state, bc) 1716 if err != nil { 1717 return err 1718 } 1719 1720 state.SubRewardBalanceByDelegateAddress(from, args.DelegateAddress, args.Amount) 1721 state.AddBalance(from, args.Amount) 1722 1723 return nil 1724 } 1725 1726 func withDrawRewardValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.WithdrawRewardArgs, error) { 1727 1728 var args neatAbi.WithdrawRewardArgs 1729 data := tx.Data() 1730 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.WithdrawReward.String(), data[4:]); err != nil { 1731 return nil, err 1732 } 1733 1734 reward := state.GetRewardBalanceByDelegateAddress(from, args.DelegateAddress) 1735 1736 if reward.Sign() < 1 { 1737 return nil, fmt.Errorf("have no reward to withdraw") 1738 } 1739 1740 if args.Amount.Sign() == -1 { 1741 return nil, fmt.Errorf("widthdraw amount can not be negative") 1742 } 1743 1744 if args.Amount.Cmp(reward) == 1 { 1745 return nil, fmt.Errorf("reward balance not enough, withdraw amount %v, but balance %v, delegate address %v", args.Amount, reward, args.DelegateAddress) 1746 } 1747 return &args, nil 1748 } 1749 1750 func registerValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1751 from := derivedAddressFromTx(tx) 1752 _, verror := registerValidation(from, tx, state, bc) 1753 if verror != nil { 1754 return verror 1755 } 1756 return nil 1757 } 1758 1759 func registerApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 1760 1761 from := derivedAddressFromTx(tx) 1762 args, verror := registerValidation(from, tx, state, bc) 1763 if verror != nil { 1764 return verror 1765 } 1766 1767 verror = updateValidation(bc) 1768 if verror != nil { 1769 return verror 1770 } 1771 1772 amount := tx.Value() 1773 1774 state.SubBalance(from, amount) 1775 state.AddDelegateBalance(from, amount) 1776 state.AddProxiedBalanceByUser(from, from, amount) 1777 1778 var blsPK goCrypto.BLSPubKey 1779 copy(blsPK[:], args.Pubkey) 1780 if verror != nil { 1781 return verror 1782 } 1783 state.ApplyForCandidate(from, blsPK.KeyString(), args.Commission) 1784 1785 verror = updateNextEpochValidatorVoteSet(tx, state, bc, from, ops) 1786 if verror != nil { 1787 return verror 1788 } 1789 1790 return nil 1791 } 1792 1793 func registerValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.RegisterArgs, error) { 1794 1795 if !state.IsCleanAddress(from) { 1796 return nil, core.ErrAlreadyCandidate 1797 } 1798 1799 if tx.Value().Cmp(minimumRegisterAmount) == -1 { 1800 return nil, core.ErrMinimumRegisterAmount 1801 } 1802 1803 var args neatAbi.RegisterArgs 1804 data := tx.Data() 1805 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.Register.String(), data[4:]); err != nil { 1806 return nil, err 1807 } 1808 1809 if err := goCrypto.CheckConsensusPubKey(from, args.Pubkey, args.Signature); err != nil { 1810 return nil, err 1811 } 1812 1813 if args.Commission > 100 { 1814 return nil, core.ErrCommission 1815 } 1816 1817 var ep *epoch.Epoch 1818 if nc, ok := bc.Engine().(consensus.NeatCon); ok { 1819 ep = nc.GetEpoch().GetEpochByBlockNumber(bc.CurrentBlock().NumberU64()) 1820 } 1821 if _, supernode := ep.Validators.GetByAddress(from.Bytes()); supernode != nil && supernode.RemainingEpoch > 0 { 1822 return nil, core.ErrCannotCandidate 1823 } 1824 1825 return &args, nil 1826 } 1827 1828 func unRegisterValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1829 from := derivedAddressFromTx(tx) 1830 verror := unRegisterValidation(from, tx, state, bc) 1831 if verror != nil { 1832 return verror 1833 } 1834 return nil 1835 } 1836 1837 func unRegisterApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 1838 1839 from := derivedAddressFromTx(tx) 1840 verror := unRegisterValidation(from, tx, state, bc) 1841 if verror != nil { 1842 return verror 1843 } 1844 1845 allRefund := true 1846 1847 state.ForEachProxied(from, func(key common.Address, proxiedBalance, depositProxiedBalance, pendingRefundBalance *big.Int) bool { 1848 1849 state.SubProxiedBalanceByUser(from, key, proxiedBalance) 1850 state.SubDelegateBalance(key, proxiedBalance) 1851 state.AddBalance(key, proxiedBalance) 1852 1853 if depositProxiedBalance.Sign() > 0 { 1854 allRefund = false 1855 1856 refunded := state.GetPendingRefundBalanceByUser(from, key) 1857 1858 state.AddPendingRefundBalanceByUser(from, key, new(big.Int).Sub(depositProxiedBalance, refunded)) 1859 1860 state.MarkDelegateAddressRefund(from) 1861 } 1862 return true 1863 }) 1864 1865 state.CancelCandidate(from, allRefund) 1866 1867 return nil 1868 } 1869 1870 func unRegisterValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1871 1872 if !state.IsCandidate(from) { 1873 return core.ErrNotCandidate 1874 } 1875 1876 var ep *epoch.Epoch 1877 if nc, ok := bc.Engine().(consensus.NeatCon); ok { 1878 ep = nc.GetEpoch().GetEpochByBlockNumber(bc.CurrentBlock().NumberU64()) 1879 } 1880 if _, supernode := ep.Validators.GetByAddress(from.Bytes()); supernode != nil && supernode.RemainingEpoch > 0 { 1881 return core.ErrCannotUnRegister 1882 } 1883 1884 if _, err := getEpoch(bc); err != nil { 1885 return err 1886 } 1887 1888 return nil 1889 } 1890 1891 func delegateValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1892 from := derivedAddressFromTx(tx) 1893 _, verror := delegateValidation(from, tx, state, bc) 1894 if verror != nil { 1895 return verror 1896 } 1897 return nil 1898 } 1899 1900 func delegateApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 1901 1902 from := derivedAddressFromTx(tx) 1903 args, verror := delegateValidation(from, tx, state, bc) 1904 if verror != nil { 1905 return verror 1906 } 1907 1908 verror = updateValidation(bc) 1909 if verror != nil { 1910 return verror 1911 } 1912 1913 amount := tx.Value() 1914 1915 state.SubBalance(from, amount) 1916 state.AddDelegateBalance(from, amount) 1917 1918 state.AddProxiedBalanceByUser(args.Candidate, from, amount) 1919 1920 verror = updateNextEpochValidatorVoteSet(tx, state, bc, args.Candidate, ops) 1921 if verror != nil { 1922 return verror 1923 } 1924 1925 return nil 1926 } 1927 1928 func delegateValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.DelegateArgs, error) { 1929 1930 if tx.Value().Sign() == -1 { 1931 return nil, core.ErrDelegateAmount 1932 } 1933 1934 var args neatAbi.DelegateArgs 1935 data := tx.Data() 1936 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.Delegate.String(), data[4:]); err != nil { 1937 return nil, err 1938 } 1939 1940 if !state.IsCandidate(args.Candidate) { 1941 return nil, core.ErrNotCandidate 1942 } 1943 1944 depositBalance := state.GetDepositProxiedBalanceByUser(args.Candidate, from) 1945 if depositBalance.Sign() == 0 { 1946 1947 delegatedAddressNumber := state.GetProxiedAddressNumber(args.Candidate) 1948 if delegatedAddressNumber >= maxDelegationAddresses { 1949 return nil, core.ErrExceedDelegationAddressLimit 1950 } 1951 } 1952 1953 var ep *epoch.Epoch 1954 if nc, ok := bc.Engine().(consensus.NeatCon); ok { 1955 ep = nc.GetEpoch().GetEpochByBlockNumber(bc.CurrentBlock().NumberU64()) 1956 } 1957 if _, supernode := ep.Validators.GetByAddress(args.Candidate.Bytes()); supernode != nil && supernode.RemainingEpoch > 0 { 1958 if depositBalance.Sign() == 0 { 1959 return nil, core.ErrCannotDelegate 1960 } 1961 } 1962 1963 return &args, nil 1964 } 1965 1966 func unDelegateValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 1967 from := derivedAddressFromTx(tx) 1968 _, verror := unDelegateValidation(from, tx, state, bc) 1969 if verror != nil { 1970 return verror 1971 } 1972 return nil 1973 } 1974 1975 func unDelegateApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 1976 1977 from := derivedAddressFromTx(tx) 1978 args, verror := unDelegateValidation(from, tx, state, bc) 1979 if verror != nil { 1980 return verror 1981 } 1982 1983 verror = updateValidation(bc) 1984 if verror != nil { 1985 return verror 1986 } 1987 1988 proxiedBalance := state.GetProxiedBalanceByUser(args.Candidate, from) 1989 var immediatelyRefund *big.Int 1990 if args.Amount.Cmp(proxiedBalance) <= 0 { 1991 immediatelyRefund = args.Amount 1992 } else { 1993 immediatelyRefund = proxiedBalance 1994 restRefund := new(big.Int).Sub(args.Amount, proxiedBalance) 1995 state.AddPendingRefundBalanceByUser(args.Candidate, from, restRefund) 1996 1997 state.MarkDelegateAddressRefund(args.Candidate) 1998 } 1999 2000 state.SubProxiedBalanceByUser(args.Candidate, from, immediatelyRefund) 2001 state.SubDelegateBalance(from, immediatelyRefund) 2002 state.AddBalance(from, immediatelyRefund) 2003 2004 verror = updateNextEpochValidatorVoteSet(tx, state, bc, args.Candidate, ops) 2005 if verror != nil { 2006 return verror 2007 } 2008 2009 return nil 2010 } 2011 2012 func unDelegateValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.UnDelegateArgs, error) { 2013 2014 var args neatAbi.UnDelegateArgs 2015 data := tx.Data() 2016 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.UnDelegate.String(), data[4:]); err != nil { 2017 return nil, err 2018 } 2019 2020 if args.Amount.Sign() == -1 { 2021 return nil, fmt.Errorf("undelegate amount can not be negative") 2022 } 2023 2024 if from == args.Candidate { 2025 return nil, core.ErrCancelSelfDelegate 2026 } 2027 2028 var ep *epoch.Epoch 2029 if nc, ok := bc.Engine().(consensus.NeatCon); ok { 2030 ep = nc.GetEpoch().GetEpochByBlockNumber(bc.CurrentBlock().NumberU64()) 2031 } 2032 if _, supernode := ep.Validators.GetByAddress(args.Candidate.Bytes()); supernode != nil && supernode.RemainingEpoch > 0 { 2033 return nil, core.ErrCannotUnBond 2034 } 2035 2036 proxiedBalance := state.GetProxiedBalanceByUser(args.Candidate, from) 2037 depositProxiedBalance := state.GetDepositProxiedBalanceByUser(args.Candidate, from) 2038 pendingRefundBalance := state.GetPendingRefundBalanceByUser(args.Candidate, from) 2039 2040 netDeposit := new(big.Int).Sub(depositProxiedBalance, pendingRefundBalance) 2041 2042 availableRefundBalance := new(big.Int).Add(proxiedBalance, netDeposit) 2043 if args.Amount.Cmp(availableRefundBalance) == 1 { 2044 return nil, core.ErrInsufficientProxiedBalance 2045 } 2046 2047 if _, err := getEpoch(bc); err != nil { 2048 return nil, err 2049 } 2050 2051 return &args, nil 2052 } 2053 2054 func setCommisstionValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 2055 from := derivedAddressFromTx(tx) 2056 _, err := setCommissionValidation(from, tx, state, bc) 2057 if err != nil { 2058 return err 2059 } 2060 2061 return nil 2062 } 2063 2064 func setCommisstionApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 2065 from := derivedAddressFromTx(tx) 2066 args, err := setCommissionValidation(from, tx, state, bc) 2067 if err != nil { 2068 return err 2069 } 2070 2071 state.SetCommission(from, args.Commission) 2072 2073 return nil 2074 } 2075 2076 func setCommissionValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.SetCommissionArgs, error) { 2077 if !state.IsCandidate(from) { 2078 return nil, core.ErrNotCandidate 2079 } 2080 2081 var args neatAbi.SetCommissionArgs 2082 data := tx.Data() 2083 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.SetCommission.String(), data[4:]); err != nil { 2084 return nil, err 2085 } 2086 2087 if args.Commission > 100 { 2088 return nil, core.ErrCommission 2089 } 2090 2091 return &args, nil 2092 } 2093 2094 func setAddressValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 2095 from := derivedAddressFromTx(tx) 2096 _, err := setAddressValidation(from, tx, state, bc) 2097 if err != nil { 2098 return err 2099 } 2100 2101 return nil 2102 } 2103 2104 func setAddressApplyCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, ops *types.PendingOps) error { 2105 from := derivedAddressFromTx(tx) 2106 args, err := setAddressValidation(from, tx, state, bc) 2107 if err != nil { 2108 return err 2109 } 2110 2111 state.SetAddress(from, args.FAddress) 2112 2113 return nil 2114 } 2115 2116 func setAddressValidation(from common.Address, tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) (*neatAbi.SetAddressArgs, error) { 2117 var args neatAbi.SetAddressArgs 2118 data := tx.Data() 2119 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.SetAddress.String(), data[4:]); err != nil { 2120 return nil, err 2121 } 2122 2123 return &args, nil 2124 } 2125 2126 func editValidatorValidateCb(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain) error { 2127 from := derivedAddressFromTx(tx) 2128 if !state.IsCandidate(from) { 2129 return errors.New("you are not a validator or candidate") 2130 } 2131 2132 var args neatAbi.EditValidatorArgs 2133 data := tx.Data() 2134 if err := neatAbi.ChainABI.UnpackMethodInputs(&args, neatAbi.EditValidator.String(), data[4:]); err != nil { 2135 return err 2136 } 2137 2138 if len([]byte(args.Details)) > maxEditValidatorLength || 2139 len([]byte(args.Identity)) > maxEditValidatorLength || 2140 len([]byte(args.Moniker)) > maxEditValidatorLength || 2141 len([]byte(args.Website)) > maxEditValidatorLength { 2142 2143 return fmt.Errorf("args length too long, more than %v", maxEditValidatorLength) 2144 } 2145 2146 return nil 2147 } 2148 2149 func concatCopyPreAllocate(slices [][]byte) []byte { 2150 var totalLen int 2151 for _, s := range slices { 2152 totalLen += len(s) 2153 } 2154 tmp := make([]byte, totalLen) 2155 var i int 2156 for _, s := range slices { 2157 i += copy(tmp[i:], s) 2158 } 2159 return tmp 2160 } 2161 2162 func getEpoch(bc *core.BlockChain) (*epoch.Epoch, error) { 2163 var ep *epoch.Epoch 2164 if nc, ok := bc.Engine().(consensus.NeatCon); ok { 2165 ep = nc.GetEpoch().GetEpochByBlockNumber(bc.CurrentBlock().NumberU64()) 2166 } 2167 2168 if ep == nil { 2169 return nil, errors.New("epoch is nil, are you running on NeatCon Consensus Engine") 2170 } 2171 2172 return ep, nil 2173 } 2174 2175 func derivedAddressFromTx(tx *types.Transaction) (from common.Address) { 2176 signer := types.NewEIP155Signer(tx.ChainId()) 2177 from, _ = types.Sender(signer, tx) 2178 return 2179 } 2180 2181 func updateValidation(bc *core.BlockChain) error { 2182 ep, err := getEpoch(bc) 2183 if err != nil { 2184 return err 2185 } 2186 2187 currHeight := bc.CurrentBlock().NumberU64() 2188 2189 if currHeight <= ep.StartBlock+2 || currHeight == ep.EndBlock { 2190 return errors.New("incorrect block height, please retry later") 2191 } 2192 2193 return nil 2194 } 2195 2196 func updateNextEpochValidatorVoteSet(tx *types.Transaction, state *state.StateDB, bc *core.BlockChain, candidate common.Address, ops *types.PendingOps) error { 2197 var update bool 2198 ep, err := getEpoch(bc) 2199 if err != nil { 2200 return err 2201 } 2202 2203 proxiedBalance := state.GetTotalProxiedBalance(candidate) 2204 depositProxiedBalance := state.GetTotalDepositProxiedBalance(candidate) 2205 pendingRefundBalance := state.GetTotalPendingRefundBalance(candidate) 2206 netProxied := new(big.Int).Sub(new(big.Int).Add(proxiedBalance, depositProxiedBalance), pendingRefundBalance) 2207 2208 if netProxied.Sign() == -1 { 2209 return errors.New("validator voting power can not be negative") 2210 } 2211 2212 currentEpochVoteSet := ep.GetEpochValidatorVoteSet() 2213 2214 if currentEpochVoteSet == nil { 2215 update = true 2216 } else { 2217 2218 if len(currentEpochVoteSet.Votes) >= updateValidatorThreshold { 2219 for _, val := range currentEpochVoteSet.Votes { 2220 2221 if val.Amount.Cmp(netProxied) == -1 { 2222 update = true 2223 break 2224 } 2225 } 2226 } else { 2227 update = true 2228 } 2229 } 2230 2231 if update && state.IsCandidate(candidate) { 2232 2233 var pubkey string 2234 pubkey = state.GetPubkey(candidate) 2235 pubkeyBytes := common.FromHex(pubkey) 2236 if pubkey == "" || len(pubkeyBytes) != 128 { 2237 return errors.New("wrong format of required field 'pub_key'") 2238 } 2239 var blsPK goCrypto.BLSPubKey 2240 copy(blsPK[:], pubkeyBytes) 2241 2242 op := types.UpdateNextEpochOp{ 2243 From: candidate, 2244 PubKey: blsPK, 2245 Amount: netProxied, 2246 Salt: "neatio", 2247 TxHash: tx.Hash(), 2248 } 2249 2250 if ok := ops.Append(&op); !ok { 2251 return fmt.Errorf("pending ops conflict: %v", op) 2252 } 2253 } 2254 2255 return nil 2256 }